Control Structures
Every Kahuna script is composed of a series of statements. A statement might involve storing, reading or deleting a key/value pair, calling a function, looping through data, or making a decision with conditional logic. This section covers the different types of statements you can use.
If/Else
The if
construct is a fundamental feature found in most programming languages. It enables conditional execution of specific blocks of code. The basic syntax looks like this:
if expression then
...
end
The expression
is evaluated as a boolean (true
or false
). If it evaluates to true
, the code inside the block is executed. If it evaluates to false
, the block is skipped.
Example:
let candidates = get by prefix `election`
if count(current_leader) == 0 then
set `election/leader` "node-A"
end
Often, you may want to perform one action when a condition is true, and a different action when it's false. That’s where else comes in. The else clause extends an if statement, allowing you to specify what should happen if the condition in the if evaluates to false.
let candidates = get by prefix `election`
if count(current_leader) == 0 then
set `election/leader` "node-A"
return true
else
return false
end
For
The for
loop allows a block of code to be executed a specific number of times or to iterate over an array of values one by one.
Repeating a block a fixed number of times:
let total = 0
for i in 1..10 do
let total = total + i
end
This loop sums the numbers from 1 to 10.
Set some candidate key/values:
set `candidates/node-a` true nx
set `candidates/node-b` true nx
Iterating over an array of values:
let candidates = get by prefix "candidates"
for candidate in candidates do
set `services/email/leader` candidate
return true
end
throw "no candidates found"
In this example, the loop looks for a valid candidate. As soon as it finds one, it sets a value and exits. If no candidates are found, it throws an error.
Begin/Commit/Rollback
All scripts are executed as a transaction by default, even if they are not explicitly wrapped in a begin
/ commit
/ rollback
block.
However, if you need finer control over when a transaction should be committed or rolled back—or if you want to customize the default transaction behavior—you can use a begin
block.
Example:
begin
let balance = get "wallet:user123"
if balance < 100 then
rollback # Insufficient funds
end
let balance = balance - 100
set "wallet:user123" balance
commit
end
Using begin
gives you full control over when to finalize or cancel a transaction based on your logic. Check the transactions section for more information about the customization options.
Let
Allows assigning values to variables. If the variable does not exist, it is automatically created in the script's temporary execution scope.
Example:
let score = 100 # temp score variable
let score = score + 50
In this example, score
is declared and assigned a value. You can reassign it freely during the script's execution, but it will cease to exist once the script ends.
If a value needs to be persisted beyond the script's execution, you must use the set
or eset
functions.
set(key, value)
stores the value durably (persistent mode).eset(key, value)
stores the value in ephemeral mode (in-memory only).
Example:
let level = 5
set `player:123:level` level # Persist the value to disk
These functions ensure that the data is stored in the key/value store and available after the script completes.
Throw
This control structure allows you to raise an exception that is propagated back to the client. When throw
is called, it automatically triggers a rollback of the transaction, undoing any uncommitted modifications.
Example:
begin
let balance = get "wallet:user123"
if balance < 100 then
throw "Insufficient funds"
end
let balance = balance - 100
set "wallet:user123" balance
commit
end
This ensures that errors are clearly communicated and that no partial updates are applied when something goes wrong.
Return
The return
statement allows you to send a value back to the client or simply stop the execution of a script early.
Examples:
return "Done"
set `config/connection-info` 'mysql://localserver-internal' nx
if not set then
return "Connection was already set"
end
Use return
to control script flow and deliver results directly from within your Kahuna Script logic.
Sleep
The sleep
command instructs the script to pause execution for the specified number of milliseconds. This can be useful for applying throttling, waiting for external coordination, or introducing slight delays between operations.
Example:
sleep 200 # pauses execution for 200 milliseconds
Use with care, as long sleep durations can impact performance and increase the risk of timeouts, especially in high-throughput systems.