Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Motivating example - task manager

Imagine you have an app (or several) that manages many different kinds of long-running tasks. And you're a stickler for avoiding unnecessary communications, so you want the client to keep track of all pending tasks and only receive status updates, never poll. So you write a reusable TaskManager interface to encapsulate the common logic of spawning, tracking, and optionally canceling tasks.

interface TaskManager<SpawnPayload, State, Error> @(Client, Server) {
    objects {
        spawn: std.Request<
            SpawnRequest<SpawnPayload>,
            result<void, SpawnError<Error>>,
        > @(Client, Server),

        cancel: std.Request<
            TaskId,
            result<void, CancelError>,
        > @(Client, Server),

        // server -> client ordered streams (per-task) of status updates
        task_status_update: std.MultiStream<TaskStatus<State>> @(Client, Server),
    }

    impl @(Server) {
        // Each TaskManager Server must specify how to spawn its tasks.
        new_task: NewTask<SpawnPayload> -> void,
    }

    methods @(Server) {
        // The server's tasks can invoke this method to send status updates to clients.
        post_status: PostTaskStatus<State> -> void,
    }

    // Clients can request to spawn and cancel tasks.
    methods @(Client) {
        spawn: async SpawnPayload -> result<SpawnSuccess, SpawnError<Error>>,
        cancel: async TaskId -> result<void, CancelError>,
    }

    state {
        // Clients will be provided a list of all pending tasks when they first connect.
        pending_tasks: [TaskId],
    }
}

struct TaskId { id: u64 }

struct SpawnSuccess {
    task_id: TaskId,
    status_stream: std.MultiStreamId,
}

// ... some definitions omitted

One of your apps is a worker for a pipeline that downloads and transcodes cat videos:

interface CatVideoTranscoder @(Client, Server) {
    objects {
        cat_video_downloads:
            TaskManager<
                CatUrl, CatVideoDownloadState, CatDownloadSpawnError,
            > @(Client, Server),

        h264_to_h265_transcoding: TaskManager<
            CatVideoId, VideoTranscodingState, VideoTranscodingSpawnError,
        > @(Client, Server),
    }
}

// ... some definitions omitted