diff options
| author | Chris Boesch <chrboesch@noreply.codeberg.org> | 2026-04-07 09:18:37 +0200 |
|---|---|---|
| committer | Chris Boesch <chrboesch@noreply.codeberg.org> | 2026-04-07 09:18:37 +0200 |
| commit | 7cb7a9948a9f5c9965fedd59f0cd816f28962fe4 (patch) | |
| tree | 1953e653faba351ab103ec030eacbfc79b7dae6c /exercises/090_async6.zig | |
| parent | 1166f3cfb65d7edc9086c6ba6b8edd4754964b33 (diff) | |
| parent | 3574fd3ae037f34510c6bb6657332b57447ac5b1 (diff) | |
Merge branch 'main' into fix-060
Diffstat (limited to 'exercises/090_async6.zig')
| -rw-r--r-- | exercises/090_async6.zig | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/exercises/090_async6.zig b/exercises/090_async6.zig new file mode 100644 index 0000000..16fb75f --- /dev/null +++ b/exercises/090_async6.zig @@ -0,0 +1,76 @@ +// +// Sometimes you want to race multiple tasks and act on whichever +// finishes first. That's what Select is for! +// +// Select is like a Group, but lets you receive individual results +// as tasks complete — one at a time: +// +// const Race = std.Io.Select(union(enum) { +// fast: u32, +// slow: u32, +// }); +// +// var buffer: [2]Race.Union = undefined; +// var sel = Race.init(io, &buffer); +// +// sel.async(.fast, fastFn, .{io}); +// sel.async(.slow, slowFn, .{io}); +// +// const winner = try sel.await(); // returns first completed +// switch (winner) { +// .fast => |val| ..., +// .slow => |val| ..., +// } +// sel.cancelDiscard(); // cancel remaining, discard results +// +// As with all async primitives: tasks spawned in a Select MUST +// be cleaned up. Use sel.cancel() to get remaining results one +// by one (for resource cleanup), or sel.cancelDiscard() if you +// don't need them. +// +// The buffer must be large enough for all tasks that might +// complete before you call cancelDiscard(). +// +// Fix this program to receive the winner of the race. +// +const std = @import("std"); +const print = std.debug.print; + +const RaceResult = std.Io.Select(union(enum) { + hare: []const u8, + tortoise: []const u8, +}); + +pub fn main(init: std.process.Init) !void { + const io = init.io; + + var buffer: [2]RaceResult.Union = undefined; + var sel = RaceResult.init(io, &buffer); + + sel.async(.hare, runHare, .{io}); + sel.async(.tortoise, runTortoise, .{io}); + + // Wait for the first finisher. + // What Select method returns the first completed result? + const winner = try sel.???(); + + switch (winner) { + .hare => |msg| print("Hare: {s}\n", .{msg}), + .tortoise => |msg| print("Tortoise: {s}\n", .{msg}), + } + + // Clean up the loser — we don't need their result. + sel.cancelDiscard(); +} + +fn runHare(io: std.Io) []const u8 { + // The hare is fast — only 1 second! + io.sleep(std.Io.Duration.fromSeconds(1), .awake) catch return "I got canceled!"; + return "I'm fast!"; +} + +fn runTortoise(io: std.Io) []const u8 { + // The tortoise is slow — 10 seconds. + io.sleep(std.Io.Duration.fromSeconds(10), .awake) catch return "I got canceled!"; + return "Slow and steady..."; +} |
