Files
ziglings/exercises/089_async5.zig
2026-04-06 16:57:48 +02:00

68 lines
2.1 KiB
Zig

//
// One of the most important features of the new Io system is
// structured cancellation!
//
// Every Future has a .cancel() method that:
// 1. Requests the task to stop (via error.Canceled at the
// next "cancellation point")
// 2. BLOCKS until the task actually finishes
// 3. Returns whatever result the task produced
//
// A "cancellation point" is any Io function that can return
// error.Canceled - most commonly io.sleep():
//
// fn myTask(io: std.Io) u32 {
// io.sleep(...) catch |err| switch (err) {
// error.Canceled => return 0, // error handle
// };
// return 42;
// }
//
// This is fundamentally different from killing a thread -
// the task gets a chance to clean up and return a value!
//
// Remember: both .await() and .cancel() block and return the
// result. The only difference is that .cancel() also sends
// the cancellation request. And both are idempotent — calling
// either one again just returns the same result.
//
// Fix this program: the slow task would take 10 seconds,
// but we cancel it after 1 second. The task should detect
// the cancellation and return early.
//
const std = @import("std");
const print = std.debug.print;
pub fn main(init: std.process.Init) !void {
const io = init.io;
var future = io.async(slowTask, .{io});
defer _ = future.cancel(io); // safety net
// Wait 1 second, then cancel instead of waiting the full 10.
io.sleep(std.Io.Duration.fromSeconds(1), .awake) catch {};
print("Canceling slow task...\n", .{});
// We don't want to wait 10 seconds!
// Which Future method requests cancellation AND returns the result?
const result = future.???(io);
print("Task returned: {}\n", .{result});
}
fn slowTask(io: std.Io) u32 {
print("Starting long computation...\n", .{});
// Try to sleep for 10 seconds - but we might get canceled!
io.sleep(std.Io.Duration.fromSeconds(10), .awake) catch |err| switch (err) {
error.Canceled => {
print("Task was canceled, cleaning up.\n", .{});
return 0;
},
};
print("Task completed normally.\n", .{});
return 42;
}