Progress & Cancellation

Planned — design subject to change

This feature is designed but not yet implemented. The syntax and behavior described here represent the target specification.

Progress reporting with emits

tape
thread Downloader {
    @pool(1, 4);

    fn download(url: string) -> []u8 emits Progress {
        let total = get_content_length(url);
        var received: i64 = 0;

        while (received < total) {
            let chunk = fetch_chunk(url, received);
            received = received + chunk.len;
            emit Progress { bytes: received; total: total; };
        }

        return buffer;
    }
}

Listening for progress

tape
Downloader.download(url) -> on_complete | on_progress;

fn on_progress(p: Progress) {
    progress_bar.set_value(p.bytes * 100 / p.total);
}

fn on_complete(data: []u8) {
    save_file(data);
}

Channel emitter type

Thread functions can accept an emitter to report to:

tape
fn scan(dir: string, out: emitter(string)) {
    for (file in list_files(dir)) {
        emit out, file;
    }
}

Cooperative cancellation

tape
thread Search {
    fn find(query: string) -> []Result {
        for (item in database) {
            @check_cancel;  // exit point if cancelled
            if (matches(item, query)) {
                results.push(item);
            }
        }
        return results;
    }
}

@check_cancel checks if the calling task has been cancelled. If so, the function returns the builtin cancel error.

Fan-out parallel processing

tape
let results = items
    |> @fan(4)
    |> process_item()
    |> collect();

@fan(N) splits work across N threads, processes in parallel, and collects results in order.

Last modified: