Documentation
¶
Overview ¶
Package durable provides embeddable durable task execution for a single OS process. Register typed tasks, run memoised steps, and resume from a local journal after a crash. A step may return ErrStepPending and complete later via CompleteStep.
e, err := durable.NewEngine(ctx, "./data")
if err != nil { ... }
defer e.Close()
_ = durable.RegisterTask(e, "process-order", durable.Func(
func(ctx context.Context, s *durable.StepRunner, in OrderInput) (OrderOutput, error) {
charged, err := durable.RunStep(ctx, s, "charge", in, func(ctx context.Context, in OrderInput) (string, error) {
return chargeCard(in)
}).Get(ctx)
if err != nil {
return OrderOutput{}, err
}
return OrderOutput{Result: charged}, nil
},
))
run := durable.RunTask[OrderInput, OrderOutput](ctx, e, "process-order", "", input)
output, err := run.Get(ctx)
Index ¶
- Variables
- func CompleteStep[O any](ctx context.Context, e *Engine, token string, result O) error
- func RegisterTask[I, O any](e *Engine, taskID string, task Task[I, O], opts ...TaskOption) error
- type Engine
- func (e *Engine) CancelRun(ctx context.Context, taskID, runID string) error
- func (e *Engine) Close() error
- func (e *Engine) DeleteTask(ctx context.Context, taskID string) error
- func (e *Engine) DeleteTaskRun(ctx context.Context, taskID, runID string) error
- func (e *Engine) GetStep(ctx context.Context, taskID, runID, stepID string) (StepRecord, bool, error)
- func (e *Engine) GetTask(ctx context.Context, taskID, runID string) (TaskInfo, bool, error)
- func (e *Engine) ListTasks(ctx context.Context, statuses ...TaskStatus) ([]TaskInfo, error)
- func (e *Engine) LoadInput(ctx context.Context, taskID, runID string) ([]byte, bool, error)
- func (e *Engine) LoadSteps(ctx context.Context, taskID, runID string) ([]StepRecord, error)
- func (e *Engine) WatchSteps(ctx context.Context, taskID, runID string, fromOffset int, ...) (<-chan StepEvent, error)
- type EngineOption
- type ReadOnlyEngine
- func (r *ReadOnlyEngine) Close() error
- func (r *ReadOnlyEngine) GetStep(ctx context.Context, taskID, runID, stepID string) (StepRecord, bool, error)
- func (r *ReadOnlyEngine) GetTask(ctx context.Context, taskID, runID string) (TaskInfo, bool, error)
- func (r *ReadOnlyEngine) ListTasks(ctx context.Context, statuses ...TaskStatus) ([]TaskInfo, error)
- func (r *ReadOnlyEngine) LoadInput(ctx context.Context, taskID, runID string) ([]byte, bool, error)
- func (r *ReadOnlyEngine) LoadSteps(ctx context.Context, taskID, runID string) ([]StepRecord, error)
- type ReadOnlyOption
- type RunOption
- type StepEvent
- type StepOption
- type StepRecord
- type StepRun
- type StepRunner
- type StepStatus
- type Task
- type TaskFunc
- type TaskInfo
- type TaskOption
- type TaskRun
- type TaskStatus
Constants ¶
This section is empty.
Variables ¶
var ( // ErrTaskNotRegistered is returned by RunTask.Get when the taskID has not // been registered on this Engine. The registry is in-memory only and must // be rebuilt after every NewEngine call. ErrTaskNotRegistered = errors.New("durable: task not registered") // ErrTaskAlreadyRegistered is returned by RegisterTask when the same // taskID is registered twice on one Engine. ErrTaskAlreadyRegistered = errors.New("durable: task already registered") // ErrRunAlreadyFinished is returned by CompleteStep when the target step // is already completed or the run is in a terminal state (completed or failed). ErrRunAlreadyFinished = errors.New("durable: run already completed or failed") // ErrRunActive is returned by DeleteTaskRun and DeleteTask when the target run // (or any run under the task) is currently executing, including while // blocked in StatusWaiting. ErrRunActive = errors.New("durable: run is currently executing") // ErrInvalidRunID is returned when a runID contains path separators or // parent-directory references that would escape the data directory. ErrInvalidRunID = errors.New("durable: invalid run ID") // ErrEngineLocked is returned by NewEngine and NewReadOnlyEngine when // dataDir is already held by another engine instance (same process or // another OS process) and the lock cannot be acquired before the timeout. ErrEngineLocked = errors.New("durable: dataDir locked by another engine") // ErrStepPending is returned from a step function to suspend that step // until CompleteStep delivers a result for it. The engine writes // StepStatusWaiting and blocks that step's Get — not the whole task. // Sibling steps started before this one keep running; call Get on them // independently or select on their Done channels. ErrStepPending = errors.New("durable: step pending external completion") // ErrInvalidToken is returned by CompleteStep when the token cannot be // decoded into taskID, runID, and stepID. ErrInvalidToken = errors.New("durable: invalid step token") // ErrRunCancelled is the error stored on a run (TaskInfo.Error, as its // string form) and returned by RunStep/Get after CancelRun. It marks // the run as StatusFailed for the same reason engine Close and task/run // timeouts already do — but with a distinct message so callers can // tell a deliberate CancelRun apart from a generic ctx cancellation or // deadline. Because TaskInfo.Error is a plain string, matching after a // resume requires comparing against ErrRunCancelled.Error(), not // errors.Is. ErrRunCancelled = errors.New("durable: run was cancelled") )
Functions ¶
func CompleteStep ¶ added in v0.1.2
CompleteStep delivers result to a suspended step identified by token. The payload is appended as a SignalEntry (durable) before the in-process waiter is signalled, so a crash after this call still resumes on the next RunTask. A second call with the same token is a no-op once the SignalEntry is on disk. Returns ErrRunAlreadyFinished if the step or run is already terminal, and ErrInvalidToken if the token cannot be decoded.
The run's status transition back to StatusRunning is owned by the waiting step itself (see leaveWaiting), not by CompleteStep — with several steps possibly waiting at once, only the step that actually resumes knows whether a sibling is still pending.
Concurrent CompleteStep calls for the same token are serialised on a per-(taskID,runID,stepID) lock distinct from the run-execution lock (which is held for the entire run, including while blocked waiting — locking it here would deadlock). A CompleteStep that loses a race with the run reaching a terminal state may append an orphan SignalEntry that is never read; this is harmless and does not corrupt the journal.
func RegisterTask ¶ added in v0.1.2
RegisterTask stores taskID → (closure + config) in the in-memory registry. Must be called before RunTask. I is the single task input type (one struct of fields, or struct{} if the task has no payload). Re-registering the same taskID returns ErrTaskAlreadyRegistered. The registry is not persisted; call this again after every NewEngine. taskID must not contain path separators or ':'.
Types ¶
type Engine ¶ added in v0.1.2
type Engine struct {
// contains filtered or unexported fields
}
Engine is the process-level entry point for durable task execution. Create one per dataDir via NewEngine. Safe for concurrent use.
Always call Close to cancel in-flight runs, release the exclusive flock, stop the purger, and close journal file handles.
func NewEngine ¶ added in v0.1.2
NewEngine opens or creates dataDir, acquires an exclusive flock on <dataDir>/.lock, and initialises the in-memory task registry. Fails with ErrEngineLocked if another Engine or ReadOnlyEngine holds the directory.
func (*Engine) CancelRun ¶ added in v0.1.3
CancelRun requests cancellation of a run. It persists a durable cancel signal — reusing the SignalEntry/CompleteStep journal plumbing via a reserved signal ID — so the intent survives a crash: on the next RunTask for this taskID/runID, the run's ctx is cancelled before Task.Exec is invoked, and every RunStep call fails fast with ErrRunCancelled instead of re-running fn. If the run is currently executing in this process, its ctx is also cancelled immediately.
Cancelling ctx only signals a step function; it cannot forcibly stop one. RunStep.Get and RunTask.Get both return promptly regardless — they select on ctx.Done() independently of whether the step's goroutine has exited. But the engine still waits for that goroutine to actually return before the run reaches a terminal state or Close/compactJournal can safely proceed (see Close). If the step function never checks ctx and never returns, that goroutine runs to completion in the background and the run stays non-terminal until it does — Close called afterward would block on it too. Write step functions so they select on ctx instead of running unconditionally to completion.
The run ends up StatusFailed (the same terminal status used for engine Close and task/run timeouts) with TaskInfo.Error set to ErrRunCancelled.Error(), so callers can distinguish a deliberate cancel from another failure by comparing that string.
Returns ErrRunAlreadyFinished if the run is already StatusCompleted or StatusFailed, or an error if taskID/runID is invalid or the run does not exist. Idempotent: calling it more than once on the same run is a no-op after the first call's signal is durably written.
func (*Engine) Close ¶ added in v0.1.2
Close cancels in-flight runs, waits for them and the auto-purger to finish writing, then releases the exclusive flock and journal handles. Safe to call more than once.
Cancelling ctx only signals — it does not forcibly stop a step function. Close waits for every in-flight RunStep goroutine to actually return (see StepRunner.waitInFlight) so a step's own journal append can never race compactJournal or a second Engine opening the same dataDir. If a step function never checks ctx and never returns, Close blocks forever and the exclusive flock on dataDir is never released. Write step functions so they select on ctx (or pass it to ctx-aware calls like http.NewRequestWithContext) instead of running unconditionally to completion.
func (*Engine) DeleteTask ¶ added in v0.1.2
DeleteTask removes all runs under taskID. Destructive — use for a full wipe only. Returns ErrRunActive if any run under taskID is currently executing (Running or Waiting in-process).
func (*Engine) DeleteTaskRun ¶ added in v0.1.2
DeleteTaskRun removes one run directory and its journal. No-op if not found. Returns ErrRunActive if the run is currently executing, including while blocked in StatusWaiting — runLocks is held for that entire duration.
func (*Engine) GetStep ¶ added in v0.1.3
func (e *Engine) GetStep(ctx context.Context, taskID, runID, stepID string) (StepRecord, bool, error)
GetStep returns the latest StepRecord for one stepID in O(1) after one journal load — (zero, false, nil) if the run has no record for that stepID yet (including one stuck mid-execution: an unfinished STARTED step never appears here — see loadJournal).
func (*Engine) GetTask ¶ added in v0.1.2
GetTask returns a single run's metadata. (zero, false, nil) if not found.
func (*Engine) ListTasks ¶ added in v0.1.2
ListTasks returns TaskInfo records. Zero args returns every status. Pass explicit statuses to filter, e.g. ListTasks(ctx, StatusRunning, StatusWaiting) for recovery after a restart.
func (*Engine) LoadInput ¶ added in v0.1.4
LoadInput returns the JSON-encoded task input written on first RunTask (one I value). (nil, false, nil) if input.json is missing.
func (*Engine) LoadSteps ¶ added in v0.1.2
LoadSteps returns all StepRecords for a run. Used to inspect progress. Includes waiting, completed, and failed steps. Order is not sorted or otherwise guaranteed — it reflects map iteration order internally. Use WatchSteps if you need append order or history.
func (*Engine) WatchSteps ¶ added in v0.1.3
func (e *Engine) WatchSteps(ctx context.Context, taskID, runID string, fromOffset int, fromByteOffset int64) (<-chan StepEvent, error)
WatchSteps streams step lifecycle events for a run: STARTED, WAITING, COMPLETED, FAILED — every append, in journal order. fromOffset (event count) or fromByteOffset (file position) skip already-seen history; fromByteOffset takes priority when non-zero (pass 0 for fromOffset if you only have a byte offset). Already-written events after that point are sent first, then each new event as it is persisted. The channel closes when ctx is cancelled or the engine closes; cancelling the watch does not stop the run. A slow consumer may miss live events — a warning is logged and delivery continues; reconnect with the last Offset/ByteOffset seen to catch up from the journal.
type EngineOption ¶ added in v0.1.2
type EngineOption func(*engineConfig)
EngineOption configures NewEngine.
func WithAutoPurge ¶
func WithAutoPurge(age time.Duration, interval ...time.Duration) EngineOption
WithAutoPurge starts a background goroutine that deletes Completed and Failed runs whose UpdatedAt is older than age. The optional interval controls how often the purger runs; it defaults to one hour. Running and Waiting runs are never purged.
func WithLockTimeout ¶ added in v0.1.2
func WithLockTimeout(d time.Duration) EngineOption
WithLockTimeout sets how long NewEngine waits for the exclusive flock. Default is 2 seconds.
func WithLogger ¶
func WithLogger(l *slog.Logger) EngineOption
WithLogger sets the slog.Logger used for task and step lifecycle events. If nil or omitted, a discard logger is used.
func WithMaxRetries ¶
func WithMaxRetries(n int) EngineOption
WithMaxRetries sets the engine-wide default for task-level retries (re-invoking the task closure). Default is 0 — retries are opt-in so non-idempotent work is not silently repeated. Overridden by WithTaskMaxRetries and WithRunMaxRetries.
func WithTimeout ¶
func WithTimeout(d time.Duration) EngineOption
WithTimeout sets the engine-wide default task deadline. Zero (default) means no timeout. Overridden by WithTaskTimeout and WithRunTimeout.
type ReadOnlyEngine ¶ added in v0.1.2
type ReadOnlyEngine struct {
// contains filtered or unexported fields
}
ReadOnlyEngine is a compile-time-restricted view of a dataDir. It acquires a shared flock so multiple readers can coexist. It cannot register or run tasks. Safe to open from a separate CLI process with no task registration.
func NewReadOnlyEngine ¶ added in v0.1.2
func NewReadOnlyEngine(dataDir string, opts ...ReadOnlyOption) (*ReadOnlyEngine, error)
NewReadOnlyEngine acquires a shared flock on <dataDir>/.lock. Multiple readers coexist. Returns ErrEngineLocked after the lock timeout if a writer holds the exclusive lock.
func (*ReadOnlyEngine) Close ¶ added in v0.1.2
func (r *ReadOnlyEngine) Close() error
Close releases the shared flock. Safe to call more than once.
func (*ReadOnlyEngine) GetStep ¶ added in v0.1.3
func (r *ReadOnlyEngine) GetStep(ctx context.Context, taskID, runID, stepID string) (StepRecord, bool, error)
GetStep returns the latest StepRecord for one stepID. Same semantics as Engine.GetStep.
func (*ReadOnlyEngine) GetTask ¶ added in v0.1.2
GetTask returns a single run's metadata. (zero, false, nil) if not found.
func (*ReadOnlyEngine) ListTasks ¶ added in v0.1.2
func (r *ReadOnlyEngine) ListTasks(ctx context.Context, statuses ...TaskStatus) ([]TaskInfo, error)
ListTasks returns TaskInfo records with the same filter semantics as Engine.ListTasks.
func (*ReadOnlyEngine) LoadInput ¶ added in v0.1.4
LoadInput returns the JSON-encoded task input written on first RunTask (one I value). Same semantics as Engine.LoadInput.
func (*ReadOnlyEngine) LoadSteps ¶ added in v0.1.2
func (r *ReadOnlyEngine) LoadSteps(ctx context.Context, taskID, runID string) ([]StepRecord, error)
LoadSteps returns all StepRecords for a run ordered by Seq.
type ReadOnlyOption ¶ added in v0.1.2
type ReadOnlyOption func(*readOnlyConfig)
ReadOnlyOption configures NewReadOnlyEngine.
func WithROLockTimeout ¶ added in v0.1.2
func WithROLockTimeout(d time.Duration) ReadOnlyOption
WithROLockTimeout sets how long NewReadOnlyEngine waits for the shared flock. Default is 2 seconds. Named distinctly from WithLockTimeout because both option types live in the same package.
func WithROLogger ¶ added in v0.1.2
func WithROLogger(l *slog.Logger) ReadOnlyOption
WithROLogger sets the slog.Logger for the read-only engine. Named distinctly from WithLogger because both option types live in the same package.
type RunOption ¶ added in v0.1.2
type RunOption func(*runConfig)
RunOption configures a single RunTask call.
func WithRunMaxRetries ¶ added in v0.1.2
WithRunMaxRetries overrides the task and engine task-level retry count for this run. An explicit 0 disables a non-zero parent default.
func WithRunTimeout ¶ added in v0.1.2
WithRunTimeout overrides the task and engine timeout for this run. An explicit 0 disables a non-zero parent timeout.
type StepEvent ¶ added in v0.1.3
type StepEvent struct {
StepRecord
Offset int
ByteOffset int64
}
StepEvent is one journal entry delivered by WatchSteps: STARTED (running), WAITING, COMPLETED, or FAILED — every append, in journal order (never last-write-wins). Offset is the 1-based position of this event across the run's whole journal (steps and signals share one counter); ByteOffset is the file position immediately after it. Reconnect with either value as fromOffset/fromByteOffset to resume a watch without missing or repeating events; byteOffset skips a full rescan, offset does not.
type StepOption ¶ added in v0.1.2
type StepOption func(*stepConfig)
StepOption configures a single RunStep call.
func WithStepMaxRetries ¶ added in v0.1.2
func WithStepMaxRetries(n int) StepOption
WithStepMaxRetries sets how many times this step's function is re-invoked on a non-panic, non-ErrStepPending error. Default is 0 (one attempt). Does not inherit from task or engine retry settings.
func WithStepTimeout ¶ added in v0.1.2
func WithStepTimeout(d time.Duration) StepOption
WithStepTimeout is an inner bound: the step deadline is min(task deadline, step timeout). It cannot extend past the task deadline. The deadline only cancels the step's ctx — it does not forcibly stop fn. A fn that never checks ctx keeps running past the deadline in the background, and the engine (Close, a later CancelRun's drain, etc.) still waits for it to actually return.
func WithStepVersion ¶ added in v0.1.4
func WithStepVersion(v string) StepOption
WithStepVersion tags this step so a later deploy can opt into re-running it. Resume still returns the cached result when the stored version equals v. If this step's code or params change and in-flight runs must re-execute it, pass a new v ("1" → "2") or rename the stepID. Empty v is a no-op (cache by stepID only). Side effects on re-run are the caller's problem.
type StepRecord ¶
type StepRecord struct {
StepID string
Version string
Input []byte
Result []byte
Error string
PanicTrace string
Status StepStatus
StartedAt time.Time
CompletedAt time.Time
}
StepRecord is the latest persistent checkpoint for one memoised step.
type StepRun ¶ added in v0.1.2
type StepRun[O any] struct { // contains filtered or unexported fields }
StepRun is the handle returned by RunStep. RunStep starts work and returns immediately; Get waits for the result, Done reports readiness without blocking so callers can select across several handles (first-of-N).
func RunStep ¶ added in v0.1.2
func RunStep[I, O any](ctx context.Context, s *StepRunner, stepID string, in I, fn func(ctx context.Context, in I) (O, error), opts ...StepOption) *StepRun[O]
RunStep starts fn as a memoised checkpoint and returns immediately. Get waits for the result. On a completed or failed cache hit, fn is not called. On a miss, fn runs on a goroutine and the result is persisted. in is a single JSON-marshalable value (one struct of fields, or struct{} if the step has no payload); it is stored on the record for inspect. stepID must be unique within the run — a duplicate panics. Concurrent calls on the same StepRunner are safe: start several steps, then Get them in any order, or select on their Done channels for first-of-N.
Step IDs are the resume key: never rename a stepID once a run has started. A renamed step is treated as a new, unrelated step — the old result is orphaned and fn runs again under the new name. To re-run the same stepID after a code or param change, pass WithStepVersion with a new string.
func (*StepRun[O]) Done ¶ added in v0.1.3
func (r *StepRun[O]) Done() <-chan struct{}
Done reports readiness. It is closed once the step completes or fails — on a cache hit it is already closed when RunStep returns. Use it in a select across multiple StepRun handles to react to whichever finishes first, then call Get to retrieve that handle's result or error.
type StepRunner ¶
type StepRunner struct {
// contains filtered or unexported fields
}
StepRunner is scoped to a single run and provides RunStep, StepToken, and run-context accessors. Concurrent RunStep calls are safe: fan out work by calling RunStep multiple times before Get-ing any handle.
func (*StepRunner) Logger ¶ added in v0.1.2
func (s *StepRunner) Logger() *slog.Logger
Logger returns the engine logger pre-scoped with taskID and runID.
func (*StepRunner) RunID ¶ added in v0.1.2
func (s *StepRunner) RunID() string
RunID returns the runID of the current run.
func (*StepRunner) StepToken ¶ added in v0.1.2
func (s *StepRunner) StepToken(ctx context.Context) string
StepToken returns an opaque token encoding taskID, runID, and the current stepID. Must be called inside a RunStep function with that function's ctx (the stepID is carried on ctx, not on the StepRunner, so concurrent steps each get their own token). Pass the token to an external caller so they can later call CompleteStep.
func (*StepRunner) TaskID ¶ added in v0.1.2
func (s *StepRunner) TaskID() string
TaskID returns the taskID of the current run.
type StepStatus ¶
type StepStatus string
StepStatus is the lifecycle state of a single step checkpoint.
const ( // StepStatusRunning means the step function is currently executing. // Watch-only: it is superseded by a terminal or waiting status once the // step finishes, and is never the record used to replay RunStep/GetStep — // an unfinished StepStatusRunning after a crash is treated as missing // (fn re-runs), not stuck. StepStatusRunning StepStatus = "running" // StepStatusWaiting means the step is suspended and awaiting CompleteStep. StepStatusWaiting StepStatus = "waiting" // StepStatusCompleted means the step succeeded and its result is cached. StepStatusCompleted StepStatus = "completed" // StepStatusFailed means the step returned an error or panicked. StepStatusFailed StepStatus = "failed" )
type Task ¶
type Task[I, O any] interface { // Exec performs the task logic. ctx is cancelled when the task timeout // elapses or the engine is closed. s is the StepRunner bound to this // run; wrap all memoised work in RunStep calls. Panics are recovered // by the engine, recorded in TaskInfo.PanicTrace, and surfaced to Get. Exec(ctx context.Context, s *StepRunner, input I) (O, error) }
Task is the execution contract for a durable task. Implementations should treat any work with external side effects as a RunStep; non-deterministic logic outside of RunStep calls may not be replayed correctly. I is the single input type (not variadic args); O is the output type. Bundle several fields in one struct. A task with no payload uses I = struct{} and RunTask(..., struct{}{}).
type TaskFunc ¶
type TaskFunc[I, O any] func(ctx context.Context, s *StepRunner, input I) (O, error)
TaskFunc adapts a plain function to Task[I, O].
type TaskInfo ¶
type TaskInfo struct {
TaskID string `json:"task_id"`
RunID string `json:"run_id"`
Name string `json:"name"`
Tags map[string]string `json:"tags"`
Status TaskStatus `json:"status"`
Error string `json:"error"`
PanicTrace string `json:"panic_trace"`
CreatedAt time.Time `json:"created_at"`
StartedAt time.Time `json:"started_at"`
CompletedAt time.Time `json:"completed_at"`
UpdatedAt time.Time `json:"updated_at"`
}
TaskInfo is the persistent metadata for a single run. The task input is stored separately in input.json (see RunTask), not on this struct.
type TaskOption ¶
type TaskOption func(*taskConfig)
TaskOption configures RegisterTask.
func WithName ¶
func WithName(name string) TaskOption
WithName sets a human-readable label stored on TaskInfo. It does not affect uniqueness or execution.
func WithTag ¶
func WithTag(k, v string) TaskOption
WithTag attaches an arbitrary key-value annotation to TaskInfo. Call multiple times to set multiple tags.
func WithTaskMaxRetries ¶ added in v0.1.2
func WithTaskMaxRetries(n int) TaskOption
WithTaskMaxRetries overrides the engine default for task-level retries (re-invoking the whole closure). Nil-vs-set is tracked so an explicit 0 disables a non-zero engine default.
func WithTaskTimeout ¶ added in v0.1.2
func WithTaskTimeout(d time.Duration) TaskOption
WithTaskTimeout overrides the engine default task deadline. An explicit 0 disables a non-zero engine default.
type TaskRun ¶ added in v0.1.2
type TaskRun[O any] struct { // contains filtered or unexported fields }
TaskRun is the handle returned by RunTask. RunID is available immediately; Get blocks until the run reaches a terminal state.
func RunTask ¶ added in v0.1.2
func RunTask[I, O any](ctx context.Context, e *Engine, taskID string, runID string, input I, opts ...RunOption) *TaskRun[O]
RunTask starts or resumes a run in a background goroutine and returns immediately. input is one typed value I — not variadic args. Put several fields on one struct; a task with no payload uses struct{} and struct{}{}. On first start the value is written to input.json. The same runID reloads that file and ignores the input argument. Pass an empty runID to resume the oldest active run for taskID, or to generate a new ULID if none is active. A completed or failed run returns the stored result without spawning a goroutine.
func (*TaskRun[O]) Get ¶ added in v0.1.2
Get blocks until the run completes or ctx is cancelled. The typed result is cached after the first successful wait so later calls do not re-decode.
func (*TaskRun[O]) RunID ¶ added in v0.1.2
RunID returns the resolved runID. Empty if the taskID was not registered or the runID was invalid — check Get for the error.
func (*TaskRun[O]) Status ¶ added in v0.1.2
func (r *TaskRun[O]) Status() TaskStatus
Status returns the current run status without blocking.
type TaskStatus ¶
type TaskStatus string
TaskStatus is the lifecycle state of a run.
const ( // StatusRunning means the run is actively executing. StatusRunning TaskStatus = "running" // StatusWaiting means at least one step is awaiting CompleteStep. StatusWaiting TaskStatus = "waiting" // StatusCompleted means the run finished successfully. StatusCompleted TaskStatus = "completed" // StatusFailed means the run terminated with an error or recovered panic. StatusFailed TaskStatus = "failed" )
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
durable-inspect
command
Command durable-inspect is a read-only viewer for a durable-go journal.
|
Command durable-inspect is a read-only viewer for a durable-go journal. |
|
examples
|
|
|
fanout
command
Package main demonstrates durable-go's async RunStep fan-out: several steps run concurrently, joined with Get; a first-of-N select reacts to whichever of two steps finishes first; one step suspends with ErrStepPending and is resumed by an external CompleteStep call.
|
Package main demonstrates durable-go's async RunStep fan-out: several steps run concurrently, joined with Get; a first-of-N select reacts to whichever of two steps finishes first; one step suspends with ErrStepPending and is resumed by an external CompleteStep call. |
|
func-task
command
Package main demonstrates the functional / closure style of durable-go.
|
Package main demonstrates the functional / closure style of durable-go. |
|
resume
command
Package main demonstrates durable-go's core value: crash recovery and step replay.
|
Package main demonstrates durable-go's core value: crash recovery and step replay. |
|
struct-task
command
Package main demonstrates the struct / method-receiver style of durable-go.
|
Package main demonstrates the struct / method-receiver style of durable-go. |
|
yaml-task
command
Package main runs a YAML workflow file as one durable-go task.
|
Package main runs a YAML workflow file as one durable-go task. |
|
Package durablepb contains the protobuf-generated wire types for journal.log entries.
|
Package durablepb contains the protobuf-generated wire types for journal.log entries. |