Skip to content

Task

Durable task definitions. A task is a state machine whose checkpoint is a Schema tagged union, with one handler per tag. A handler advances the task only by committing through TaskRuntime.commit, atomically with the entries, state and child tasks it wrote. There is no replay of a function body: after a crash the task re-enters the handler of its last committed checkpoint.

import { Next, Task, TaskRuntime } from "@effective-harness/core"
import * as Effect from "effect/Effect"
import * as Schema from "effect/Schema"
const Payment = Task.make("app.payment", {
version: 1,
input: Schema.Struct({ card: Schema.String }),
checkpoint: Schema.TaggedUnion({ Charge: {} }),
initial: () => ({ _tag: "Charge" }),
phases: {
Charge: (task) => TaskRuntime.commit(Effect.succeed(Next.complete({ card: task.input.card })))
},
abort: () => TaskRuntime.commit(Effect.succeed(Next.aborted()))
})

Since v0.0.0


A task definition of any shape, as the registry holds it.

Signature

type Any = Task<any, any, any>

Source

Since v0.0.0

Any checkpoint: a tagged union member.

Signature

export interface Checkpoint {
readonly _tag: string
}

Source

Since v0.0.0

The checkpoint union of a task.

Signature

type CheckpointOf<T extends Any> = T extends Task<any, infer C, any> ? C : never

Source

Since v0.0.0

The input type of a task.

Signature

type Input<T extends Any> = T extends Task<infer I, any, any> ? I : never

Source

Since v0.0.0

Signature

export interface Options<I, C extends Checkpoint, R> {
/** Positive integer version of the stored input and checkpoint shapes. */
readonly version: number
readonly input: Schema.Codec<I, any, never, never>
/** A `Schema.TaggedUnion` of the task's phases. */
readonly checkpoint: Schema.Codec<C, any, never, never>
/** Codec of the completed result; defaults to any JSON value. */
readonly result?: Schema.Codec<R, any, never, never>
/** The first checkpoint of a new task. */
readonly initial: (input: I) => NoInfer<C>
readonly phases: Phases<I, C>
/**
* Runs once, after the task's ordinary owned work is gone, when the task has an abort mark. It must commit a
* terminal outcome, usually `Next.aborted()`; returning without one faults the task. It cannot wait. Default: commit
* `Next.aborted()`, for tasks with nothing to undo.
*/
readonly abort?: (task: RunningTask<I, C>) => Effect.Effect<void, unknown, TaskRuntime>
/**
* Convert a task stored by an older version, given its encoded input and checkpoint. Runs at reservation. If it
* throws, the task stays blocked.
*/
readonly migrate?: (
input: Json,
checkpoint: Json,
fromVersion: number
) => { readonly input: NoInfer<I>; readonly checkpoint: NoInfer<C> }
}

Source

Since v0.0.0

One phase of a task. Failing, or dying, faults the task; so does returning without committing progress.

Signature

type PhaseHandler<I, C> = (task: RunningTask<I, C>) => Effect.Effect<void, unknown, TaskRuntime>

Source

Since v0.0.0

One handler per checkpoint tag; a missing tag is a type error.

Signature

type Phases<I, C extends Checkpoint> = {
readonly [K in C["_tag"]]: PhaseHandler<I, Extract<C, { readonly _tag: K }>>
}

Source

Since v0.0.0

The result type of a task.

Signature

type Result<T extends Any> = T extends Task<any, any, infer R> ? R : never

Source

Since v0.0.0

The committed record of a running task, with its input and checkpoint decoded.

Signature

export interface RunningTask<I, C> {
readonly id: TaskId
readonly conversationId: ConversationId
readonly kind: string
readonly version: number
readonly input: I
/** Owning task of a child task; absent for a task its conversation owns. */
readonly owner?: TaskId
readonly background: boolean
readonly abortRequested: boolean
readonly checkpoint: C
readonly memos?: { readonly [name: string]: Json }
}

Source

Since v0.0.0

A task definition.

Signature

export interface Task<I, C extends Checkpoint, R> extends Options<I, C, R> {
readonly [TypeId]: typeof TypeId
readonly name: string
readonly result: Schema.Codec<R, any, never, never>
readonly abort: (task: RunningTask<I, C>) => Effect.Effect<void, unknown, TaskRuntime>
/** @internal JSON codecs of the stored shapes. */
readonly codecs: {
readonly input: Schema.Codec<I, Json>
readonly checkpoint: Schema.Codec<C, Json>
readonly result: Schema.Codec<R, Json>
}
}

Source

Since v0.0.0

Signature

declare const TypeId: "~@effective-harness/core/Task"

Source

Since v0.0.0

Wait for a task’s outcome, whatever it is: completed, failed, aborted, orphaned or faulted. Interrupting the caller only stops the wait. Fails with TaskNotFound for an unknown task.

Signature

declare const await: (
id: TaskId
) => Effect.Effect<TaskOutcome, TaskNotFound | SchedulerClosed | StorageFailure | SessionPoisoned, Scheduler>

Source

Since v0.0.0

The committed task record; None for an unknown ID. Never starts scheduling.

Signature

declare const get: (id: TaskId) => Effect.Effect<Option.Option<TaskRecord>, StorageFailure | SessionPoisoned, Session>

Source

Since v0.0.0

Signature

declare const isTask: (value: unknown) => value is Any

Source

Since v0.0.0

Define a task.

Signature

declare const make: <I, const C extends Checkpoint, R = Schema.Json>(
name: string,
options: Options<I, C, R>
) => Task<I, C, R>

Source

Since v0.0.0