Skip to content

worker

import "github.com/danmestas/dagnats/worker"

Task execution framework for building DagNats workers. Handles NATS subscription management, message acknowledgment, retry/NAK logic, heartbeat registration, and the task context API that handlers use.

Key Types

TypeDescription
WorkerCore worker runtime: manages NATS subscriptions, dispatches tasks to handlers, handles lifecycle
TaskContextInterface passed to handlers: provides input, completion, failure, checkpointing, and signal methods
WorkerRegistrationMetadata registered in the workers KV bucket for discovery

Worker Lifecycle

  1. Create a worker with NewWorker(nc, opts...). Options are WithGroups, WithPartitions and WithControlPlane.
  2. Register handlers with Handle(taskType, fn, opts...), HandleSingleton(taskType, fn) or the generic HandleTyped(w, taskType, fn).
  3. Call Start() to create the consumers. It returns once they are running, so keep the process alive yourself.
  4. Call Stop() to stop consuming and wait up to 30 seconds for running handlers.

Handle vs HandleTyped

FunctionSignatureInput Access
(*Worker).Handlefunc(ctx TaskContext) errorctx.Input() returns raw []byte
HandleTyped[I, O]func(ctx TaskContext, input I) (O, error)Automatic JSON unmarshal into I, marshal O on return

HandleTyped is a generic convenience wrapper. It unmarshals the input, calls your function, and completes with the marshaled output on a nil error. Pass worker.UnwrapTrigger() to receive the data of a trigger envelope instead of the envelope.

TaskContext Methods

MethodDescription
Input() []byteRaw input JSON
RunID() string, StepID() stringRun and step IDs
RetryCount() int0 on the first dispatch, then the attempt number (2, 3, …) on engine retries
Metadata() map[string]stringThe step’s static metadata
Context() context.ContextContext of the task
Complete(output []byte) errorFinish the step
Fail(err error) errorFail the attempt; the retry policy applies
FailPermanent(err error) errorFail without retrying
FailRetryAfter(err error, d time.Duration) errorFail and retry after d
Continue(output []byte) errorRequest next agent-loop iteration
Heartbeat() errorExtend the claim on the task
PutStream(data []byte) errorPublish a live token to stream.{run_id}.{step_id}
LogOut() io.Writer, LogErr() io.WriterStream stdout and stderr chunks into the run’s logs
Checkpoint(state []byte) errorSave state to the checkpoints KV
LoadCheckpoint() ([]byte, error)Load previously saved state
Pause(name string, d time.Duration) errorSave a pause marker and run the handler again after d
WaitForSignal(name string, timeout time.Duration) ([]byte, error)Block until a named signal arrives
SendSignal(runID, name string, data []byte) errorSend a signal
ControlPlane() ControlPlaneControl-plane handle, or nil

Error Helpers

FunctionDescription
NewNonRetryableError(err)Return it from a handler to fail permanently with no retry
NewRateLimitError(err, d)Return it from a handler to retry after d

Both are detected with errors.As, so they can be wrapped.

Usage

nc, _ := nats.Connect("nats://localhost:4222")
w := worker.NewWorker(nc)

w.Handle("process", func(ctx worker.TaskContext) error {
    input := ctx.Input()
    result := doWork(input)
    return ctx.Complete(result)
})

w.Start() // returns once consumers are running
defer w.Stop()