summaryrefslogtreecommitdiff
path: root/exercises/089_async5.zig
blob: 4fb8d76a87c6daacbeebe7c6d00c9691ff46bcf0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//
// 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. Waits for the task to actually finish
//   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,  // handle gracefully
//         };
//         return 42;
//     }
//
// This is fundamentally different from killing a thread -
// the task gets a chance to clean up and return a value!
//
// 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});

    // 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 = ???;

    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;
}