Tasks Never Leak
● Advanced4 minBefore this: TasksSpec 9.2
A task can't outlive the function that spawned it: when the function returns, its tasks still running are cancelled.
use std.time
fn watch() {
const _ticker = spawn {
for tick in time.every_ms(100) {
print("tick {tick}")
}
}
time.sleep_ms(350)
}
fn main() {
watch()
print("watching stopped")
}The program ran and printed:
kavach run cancel.kav
tick 0tick 1tick 2watching stopped
watch spawns a ticker that would tick forever, then returns after 350 ms. The ticker is cancelled at that moment, so nothing keeps running in the background by mistake.
When one part fails, the others stop
use std.time
fn slow_part() -> Int uses Clock, Console {
time.sleep_ms(300)
print("slow part finished")
1
}
fn broken_part() -> Int ! Error uses Clock {
time.sleep_ms(50)
fail Error("the second part broke")
}
fn both() -> Int ! Error uses Clock, Console {
const a = spawn slow_part()
const b = spawn broken_part()
const _ = try b.wait()
try a.wait()
}
fn main() {
const _ = both() catch e => {
print("both failed: {e}")
0
}
print("main goes on; the slow part never printed")
}The program ran and printed:
kavach run siblings.kav
both failed: the second part brokemain goes on; the slow part never printed
try b.wait() passes the error on, so both returns, and its other task, still sleeping, is cancelled before it prints. No half-finished work goes on unseen.
Why it matters: in languages where tasks run on their own, a forgotten task can leak memory, hold a connection or write after the program thought it was done. Here the code's shape says how long every task lives.