Documentation
¶
Overview ¶
Package packtrail is a durable workflow engine built only on NATS JetStream. It is event-sourced: every execution is an ordered log of events on its own subject, the single source of truth from which state, snapshots, indexes, jobs and timers are derived. It interprets a declarative graph (tasks, choices, fan-out/join, awaits, dynamic maps, subflows) with typed state channels and reducers, durable timers, interrupts, time travel and forks — and it is agnostic: a task is work done by a worker of some kind, in any language, over a versioned NATS protocol.
An Engine processes commands and dispatches work; a Client starts and drives executions; workers (package worker) execute tasks.
Index ¶
- Constants
- Variables
- func IsTerminal(ev event.Event) bool
- func ValidateCron(expr string) error
- func ValidateName(what, s string) error
- func ValidateNamespace(ns string) error
- func ValidateOptions(opts ...Option) error
- type Client
- func (c *Client) Cancel(ctx context.Context, execID, reason string) error
- func (c *Client) DeadLetters(ctx context.Context, limit int) ([]DeadLetter, error)
- func (c *Client) Flow(ctx context.Context, name, version string) (*flow.Flow, error)
- func (c *Client) Flows(ctx context.Context) ([]FlowVersion, error)
- func (c *Client) Fork(ctx context.Context, execID string, seq uint64, opts ...ForkOption) (string, error)
- func (c *Client) Get(ctx context.Context, execID string) (*State, error)
- func (c *Client) History(ctx context.Context, execID string) ([]event.Event, error)
- func (c *Client) List(ctx context.Context, f ListFilter) ([]Summary, error)
- func (c *Client) OutputHistory(ctx context.Context, execID, node string) ([]json.RawMessage, error)
- func (c *Client) Progress(ctx context.Context, execID string) (<-chan Progress, error)
- func (c *Client) Quarantined(ctx context.Context) ([]string, error)
- func (c *Client) Redrive(ctx context.Context, seq uint64) error
- func (c *Client) Register(ctx context.Context, def *flow.Flow) (string, error)
- func (c *Client) Rerun(ctx context.Context, execID, node string, opts ...ForkOption) (string, error)
- func (c *Client) Resume(ctx context.Context, execID, node string, value any) error
- func (c *Client) Schedule(ctx context.Context, name, flowName, cron string, input any, ...) error
- func (c *Client) Schedules(ctx context.Context) ([]ScheduleInfo, error)
- func (c *Client) Signal(ctx context.Context, execID, name string, payload any, opts ...SignalOption) error
- func (c *Client) Start(ctx context.Context, flowName string, input any, opts ...StartOption) (string, error)
- func (c *Client) StateAt(ctx context.Context, execID string, seq uint64) (*State, error)
- func (c *Client) Store() *Store
- func (c *Client) Unquarantine(ctx context.Context, execID string) error
- func (c *Client) Unschedule(ctx context.Context, name string) error
- func (c *Client) Update(ctx context.Context, execID string, writes map[string]any, ...) (*State, error)
- func (c *Client) Wait(ctx context.Context, execID string) (*State, error)
- func (c *Client) WaitUntil(ctx context.Context, execID string, cond func(*State) bool) (*State, error)
- func (c *Client) Watch(ctx context.Context, execID string, from uint64) (<-chan event.Event, error)
- func (c *Client) WatchTerminal(ctx context.Context, fromSeq uint64) (<-chan Ended, error)
- type ClientOption
- type DeadLetter
- type Ended
- type Engine
- func (e *Engine) Archive(ctx context.Context, execID string) error
- func (e *Engine) Client() *Client
- func (e *Engine) Init(ctx context.Context) error
- func (e *Engine) Metrics(ctx context.Context) Metrics
- func (e *Engine) Partitions() int
- func (e *Engine) Ready() <-chan struct{}
- func (e *Engine) RebuildIndex(ctx context.Context) (int, error)
- func (e *Engine) Register(ctx context.Context, def *flow.Flow) (string, error)
- func (e *Engine) Run(ctx context.Context) error
- type FlowVersion
- type ForkOption
- type ListFilter
- type Metrics
- type Option
- func WithAckWait(d time.Duration) Option
- func WithBlobThreshold(n int) Option
- func WithBlobTimeout(d time.Duration) Option
- func WithClock(now func() time.Time) Option
- func WithDrainTimeout(d time.Duration) Option
- func WithFlow(def *flow.Flow) Option
- func WithFlowYAML(yaml []byte) Option
- func WithFlowsDir(dir string) Option
- func WithHistoryLimit(n int) Option
- func WithLogger(l *slog.Logger) Option
- func WithNamespace(ns string) Option
- func WithOwnedPartitions(ps ...int) Option
- func WithPartitions(n int) Option
- func WithPullExpiry(d time.Duration) Option
- func WithReadTimeout(d time.Duration) Option
- func WithReplicas(n int) Option
- func WithSchedule(name, flowName, cron string, input any) Option
- func WithSnapshotEvery(n int) Option
- func WithStateCacheSize(n int) Option
- func WithoutCommands() Option
- func WithoutDispatcher() Option
- type Progress
- type ScheduleInfo
- type ScheduleOption
- type SignalOption
- type StartOption
- type State
- type Status
- type Store
- type Summary
- type UpdateOption
Examples ¶
Constants ¶
const ( StatusRunning = fold.StatusRunning StatusWaiting = fold.StatusWaiting StatusCompleted = fold.StatusCompleted StatusFailed = fold.StatusFailed StatusCancelled = fold.StatusCancelled )
Execution statuses.
const DefaultHistoryLimit = 10000
DefaultHistoryLimit is the live log length (events) past which an execution is continued as new under the same id.
Variables ¶
var ( // ErrNotFound means the execution does not exist (and was never archived), // or a Store key has no value. ErrNotFound = apierr.ErrNotFound // ErrArchived means the execution finished and was archived: it can be // read, but not driven any more (I-17). ErrArchived = errors.New("packtrail: execution is archived") // ErrInvalidArgument wraps every validation error of caller input // (malformed ids, names, payloads). ErrInvalidArgument = apierr.ErrInvalidArgument // ErrUnknownFlow means the flow (or version) is not registered. ErrUnknownFlow = errors.New("packtrail: unknown flow") // ErrTerminal means the execution already reached a final status. ErrTerminal = errors.New("packtrail: execution already finished") // ErrNoValue means a value State decodes (a result, a channel, a signal, // the output) is absent. ErrNoValue = fold.ErrNoValue )
Errors returned by the public API. They are sentinel values: test with errors.Is.
Functions ¶
func IsTerminal ¶ added in v1.0.0
IsTerminal reports whether ev ends an execution.
func ValidateCron ¶ added in v0.2.0
ValidateCron checks a cron expression as schedules accept it: six fields (second minute hour day-of-month month day-of-week) or a predefined "@..." form. The error wraps ErrInvalidArgument.
func ValidateName ¶ added in v1.0.0
ValidateName checks an identifier that becomes a single NATS subject token or KV key segment — flow names, node ids, signal names, worker kinds, schedule names, execution ids: it must match [A-Za-z0-9_-]{1,128}. what names the identifier in the message ("flow name", …). The error wraps ErrInvalidArgument.
func ValidateNamespace ¶ added in v0.2.0
ValidateNamespace checks a namespace prefix (WithNamespace, WithClientNamespace, worker.WithNamespace): it must match [A-Za-z0-9_-]{1,64}. The error wraps ErrInvalidArgument.
func ValidateOptions ¶ added in v1.0.0
ValidateOptions runs every check New does on opts without a connection, so a configuration (flows, schedules, namespace, tuning) can be validated offline. It does no network I/O; WithFlowsDir still reads its directory.
Example ¶
package main
import (
"fmt"
"github.com/henomis/packtrail"
)
func main() {
// Check a configuration without a NATS connection, e.g. in a CI lint step.
err := packtrail.ValidateOptions(
packtrail.WithNamespace("tenant-a"),
packtrail.WithSchedule("nightly", "report", "0 0 3 * * *", nil),
)
fmt.Println(err)
err = packtrail.ValidateOptions(packtrail.WithSchedule("nightly", "report", "0 3 * * *", nil))
fmt.Println(err != nil)
}
Output: <nil> true
Types ¶
type Client ¶ added in v1.0.0
type Client struct {
// contains filtered or unexported fields
}
Client starts, drives and inspects executions. It is safe for concurrent use and needs only a NATS connection: it can live in any process.
func NewClient ¶ added in v1.0.0
func NewClient(nc *nats.Conn, opts ...ClientOption) (*Client, error)
NewClient returns a client. It performs no I/O; the namespace is attached on first use.
func (*Client) Cancel ¶ added in v1.0.0
Cancel cancels an execution. Cancelling a finished execution is a no-op.
func (*Client) DeadLetters ¶ added in v1.0.0
DeadLetters returns the most recent dead letters, newest first.
func (*Client) Flows ¶ added in v1.0.0
func (c *Client) Flows(ctx context.Context) ([]FlowVersion, error)
Flows lists the registered flow versions.
func (*Client) Fork ¶ added in v1.0.0
func (c *Client) Fork(ctx context.Context, execID string, seq uint64, opts ...ForkOption) (string, error)
Fork creates a new execution from the state of execID right after the event at sequence seq (rounded up to the end of that decision), and continues it from there: what was in flight is dispatched again. The source is untouched. Like Start, it returns once the new execution exists.
func (*Client) Get ¶ added in v1.0.0
Get returns the current state of an execution (archived executions are read from the archive, with Archived set).
func (*Client) History ¶ added in v1.0.0
History returns every event of an execution, in order, including the stretches archived when it was continued as new.
func (*Client) List ¶ added in v1.0.0
List returns indexed executions matching the filter, newest first.
func (*Client) OutputHistory ¶ added in v1.0.0
OutputHistory returns every output a node produced, oldest first: one per completed visit (results only keep the latest, I-14).
func (*Client) Progress ¶ added in v1.0.0
Progress streams the progress messages workers publish for execID, as they arrive: LangGraph's "custom" stream mode. Messages are not stored, so only those published after the subscription are received; to see an execution from its first step, choose its id (WithExecutionID) and subscribe before Start. The channel closes when ctx ends or the execution finishes (after the messages already received).
func (*Client) Quarantined ¶ added in v1.0.0
Quarantined lists the executions the dispatcher gave up on (an event it could not process; the dead letters say why). Their state is readable up to the bad event; continue one with Fork from an earlier sequence.
func (*Client) Redrive ¶ added in v1.0.0
Redrive re-publishes the dead letter at seq to its original subject (with a fresh deduplication id) and removes it from the dead-letter stream.
func (*Client) Register ¶ added in v1.0.0
Register stores a flow definition and returns its version hash.
func (*Client) Rerun ¶ added in v1.0.0
func (c *Client) Rerun(ctx context.Context, execID, node string, opts ...ForkOption) (string, error)
Rerun forks execID at the point where node was last entered, so the node (and everything after it) runs again in a new execution. Any node can be rerun: a task or a map runs its work again, a subflow starts a new child, an await waits again.
func (*Client) Resume ¶ added in v1.0.0
Resume re-runs an interrupted node, passing value to its worker as `resume` (human-in-the-loop, LangGraph interrupt()).
func (*Client) Schedule ¶ added in v1.0.0
func (c *Client) Schedule(ctx context.Context, name, flowName, cron string, input any, opts ...ScheduleOption, ) error
Schedule installs (or replaces) a cron schedule that starts flowName with input on every firing. It is a JetStream message schedule: no process keeps time, any engine turns the firing into an execution "<name>-<seq>".
func (*Client) Schedules ¶ added in v1.0.0
func (c *Client) Schedules(ctx context.Context) ([]ScheduleInfo, error)
Schedules lists the installed cron schedules.
func (*Client) Signal ¶ added in v1.0.0
func (c *Client) Signal(ctx context.Context, execID, name string, payload any, opts ...SignalOption) error
Signal delivers a named signal to an execution. A signal sent before the execution reaches the matching await is buffered, never lost (I-09); a signal to a missing execution is an error.
func (*Client) Start ¶ added in v1.0.0
func (c *Client) Start(ctx context.Context, flowName string, input any, opts ...StartOption) (string, error)
Start starts an execution of flowName with input (a JSON object, a struct or nil) and returns its id once the execution exists: Signal, Cancel, Resume, Update and Get can address it right away. It needs a running engine, and fails with ErrInvalidArgument when the engine refuses the input. The execution itself runs asynchronously; use Wait, WaitUntil or Watch to follow it. If ctx ends first the execution may still start: retry with the same WithExecutionID.
func (*Client) StateAt ¶ added in v1.0.0
StateAt returns the state of an execution as it was right after the event at stream sequence seq (0 = now): time travel.
func (*Client) Unquarantine ¶ added in v1.0.0
Unquarantine resumes a quarantined execution once the cause is fixed (for example after upgrading to a version that understands its events): the effects of every event from the failing one are replayed and the dispatchers stop skipping it. It is asynchronous; if replaying still fails the execution stays quarantined and the command is dead-lettered.
func (*Client) Unschedule ¶ added in v1.0.0
Unschedule removes a cron schedule.
func (*Client) Update ¶ added in v1.0.0
func (c *Client) Update(ctx context.Context, execID string, writes map[string]any, opts ...UpdateOption, ) (*State, error)
Update writes channels of a running execution (through their reducers) and returns its state right after the write: a synchronous, validated change from outside the graph (Temporal's Update, LangGraph's update_state). Tasks scheduled from then on see the new values. It fails with ErrInvalidArgument when a channel is undeclared or a value does not fit its reducer, and with ErrTerminal when the execution already finished. If ctx ends first the update may still be applied: retry with the same WithUpdateID.
func (*Client) Wait ¶ added in v1.0.0
Wait blocks until the execution finishes and returns its final state. It watches event headers only (no payloads are fetched while waiting).
Only ctx ends a wait early, besides an invalid id: a read that fails (a timeout under load, a leader election) is retried with backoff instead of being returned to a caller that asked to wait.
func (*Client) WaitUntil ¶ added in v1.0.0
func (c *Client) WaitUntil(ctx context.Context, execID string, cond func(*State) bool) (*State, error)
WaitUntil blocks until cond holds on the execution's state and returns that state: wait until it parks at an await, opens a task, reaches a status. cond is checked on the current state, then each time the execution's log is caught up after a decision; a state the execution only passes through between two checks may be missed, so test what lasts (an open await, a result) rather than what flashes by. If the execution finishes without cond holding, WaitUntil returns its final state and ErrTerminal. Like Wait, only ctx ends it early.
func (*Client) Watch ¶ added in v1.0.0
Watch streams the events of an execution from sequence from (0 = the beginning), as they are appended: LangGraph's "updates" stream mode. The channel closes after the terminal event or when ctx ends.
func (*Client) WatchTerminal ¶ added in v1.0.0
WatchTerminal streams the end of every execution in the namespace (subflow children included) from stream sequence fromSeq, or from now when fromSeq is 0: one consumer for all executions instead of a Wait per execution. It reads only event headers, never bodies. Endings arrive in log order, once each, across reconnects (the ordered consumer resumes after the last message it delivered); a slow reader slows the watch instead of losing endings. The channel closes when ctx ends or the connection is closed.
type ClientOption ¶ added in v1.0.0
ClientOption configures a Client.
func WithClientBlobTimeout ¶ added in v1.0.0
func WithClientBlobTimeout(d time.Duration) ClientOption
WithClientBlobTimeout bounds one claim-check transfer when the caller's context has no deadline (default 2m).
func WithClientNamespace ¶ added in v1.0.0
func WithClientNamespace(ns string) ClientOption
WithClientNamespace sets the namespace (default "packtrail").
func WithClientReadTimeout ¶ added in v1.0.0
func WithClientReadTimeout(d time.Duration) ClientOption
WithClientReadTimeout bounds one batched read of an event log (default 5s).
type DeadLetter ¶ added in v0.1.0
type DeadLetter = wire.DeadLetter
DeadLetter is a message packtrail gave up on: an invalid command, a job whose deliveries were exhausted, an undeliverable trigger.
type Ended ¶ added in v1.0.0
type Ended struct {
ExecID string
// Status is completed, failed or cancelled; Get has the reason and error.
Status Status
// Seq is the stream sequence of the terminal decision: pass Seq+1 to
// WatchTerminal to resume after it.
Seq uint64
}
Ended reports that an execution finished.
type Engine ¶ added in v1.0.0
type Engine struct {
// contains filtered or unexported fields
}
Engine runs packtrail: command processing per partition, the dispatcher, cron and triggers.
func New ¶
New validates the configuration and returns an Engine. It performs no I/O (I-10): resources are provisioned by Init (or lazily by Run).
Example ¶
package main
import (
"fmt"
"github.com/henomis/packtrail"
)
func main() {
// New only validates options; Init (or Run) provisions the namespace.
_, err := packtrail.New(nil)
fmt.Println(err != nil)
_, err = packtrail.New(nil, packtrail.WithNamespace("bad.name"))
fmt.Println(err != nil)
}
Output: true true
func (*Engine) Archive ¶ added in v1.0.0
Archive archives a terminal execution now, regardless of retention. Archiving an archived execution is a no-op; a missing one is ErrNotFound and one still running is ErrInvalidArgument.
func (*Engine) Client ¶ added in v1.0.0
Client returns a client bound to this engine's namespace. Valid after Init.
func (*Engine) Init ¶ added in v1.0.0
Init provisions the namespace (streams, buckets, object stores), checks the server, registers the configured flows and installs the configured schedules. It is idempotent.
func (*Engine) Metrics ¶ added in v1.0.0
Metrics returns the engine counters and the dispatcher lag.
func (*Engine) Partitions ¶ added in v1.0.0
Partitions returns the deployed partition count. Valid after Init.
func (*Engine) Ready ¶ added in v1.0.0
func (e *Engine) Ready() <-chan struct{}
Ready returns a channel closed once Run has provisioned the namespace and every consumer of this process (commands, dispatch, cron, triggers) is pulling: the signal for a readiness probe. It stays open if Run fails first, and once Run returns Ready gives a new, open channel: call it at each probe. It reports start-up only, not later connectivity.
func (*Engine) RebuildIndex ¶ added in v1.0.0
RebuildIndex rebuilds the visibility index from the event log: every execution in the events stream is folded and its summary rewritten. The index is a projection, so it can always be recovered this way.
type FlowVersion ¶ added in v1.0.0
FlowVersion describes a registered flow version.
type ForkOption ¶ added in v1.0.0
type ForkOption func(*forkOpts)
ForkOption configures Fork and Rerun.
func WithForkID ¶ added in v1.0.0
func WithForkID(id string) ForkOption
WithForkID sets the id of the new execution.
func WithForkWrites ¶ added in v1.0.0
func WithForkWrites(writes map[string]any) ForkOption
WithForkWrites edits the fork's channels (through their reducers) before it resumes: change the state at the fork point, then continue — LangGraph's update_state. The writes are checked against the flow before the fork is requested.
type ListFilter ¶ added in v1.0.0
type ListFilter struct {
Status Status
Flow string
// Attr / Value select by a declared search attribute.
Attr string
Value string
Limit int
}
ListFilter selects executions in List. Empty fields match everything.
type Option ¶
type Option func(*config) error
Option configures an Engine.
func WithAckWait ¶ added in v1.0.0
WithAckWait sets the ack wait of the engine's consumers (commands, events, cron, triggers). Handlers heartbeat while they run, so this is not a limit on how long a command may take: it is how long a message held by a crashed process waits before another engine gets it (default 5s).
func WithBlobThreshold ¶ added in v1.0.0
WithBlobThreshold sets the body size above which messages use the claim-check (default: server max_payload minus a margin).
func WithBlobTimeout ¶ added in v1.0.0
WithBlobTimeout bounds one claim-check transfer when the caller's context has no deadline (default 2m). Raise it for very large payloads on slow links.
func WithDrainTimeout ¶ added in v0.1.0
WithDrainTimeout bounds the graceful drain on shutdown (default 30s). A non-positive value keeps the default.
func WithFlowYAML ¶ added in v1.0.0
WithFlowYAML parses and registers a flow definition at Init.
func WithFlowsDir ¶
WithFlowsDir registers every *.yaml / *.yml flow of dir at Init.
func WithHistoryLimit ¶ added in v1.0.0
WithHistoryLimit continues an execution as new once its live log holds n events (default 10 000; negative disables): the log so far is archived as a segment and replaced by one event carrying the folded state. Behaviour does not change — same id, state, in-flight work and timers — and History, StateAt, Fork and Rerun still see everything. A looping execution's log then stays bounded (G5-07).
func WithLogger ¶ added in v1.0.0
WithLogger sets the logger.
func WithNamespace ¶
WithNamespace sets the namespace prefix of every NATS resource (default "packtrail"): independent deployments can share a cluster.
func WithOwnedPartitions ¶ added in v1.0.0
WithOwnedPartitions restricts this engine to some partitions (default: it competes for all of them; pinned consumers make one engine active per partition and fail over automatically).
func WithPartitions ¶ added in v1.0.0
WithPartitions sets the partition count of a new deployment (default 64). It cannot change once the namespace is provisioned.
func WithPullExpiry ¶ added in v1.0.0
WithPullExpiry sets how long the engine's pull requests live on the server (default 5s). Shorter values hand partitions over faster after a crash.
func WithReadTimeout ¶ added in v1.0.0
WithReadTimeout bounds one batched read of an event log (default 5s).
func WithReplicas ¶ added in v1.0.0
WithReplicas sets the replication factor of every stream, KV bucket and object store. Without it, existing resources keep the replication they are deployed with and new ones get 1, so an engine started without the option never scales a replicated deployment down. Use 3 in production: the events stream is the source of truth. Changing it scales the resources at the next Init; the cluster must have enough JetStream servers.
func WithSchedule ¶ added in v1.0.0
WithSchedule installs a cron schedule at Init. The expression is validated here, so a typo fails at New instead of inside the engine (I-22).
func WithSnapshotEvery ¶ added in v1.0.0
WithSnapshotEvery snapshots states every n events (default 100; negative disables snapshots).
func WithStateCacheSize ¶ added in v1.0.0
WithStateCacheSize bounds the in-memory state caches (default 10000).
func WithoutCommands ¶ added in v1.0.0
func WithoutCommands() Option
WithoutCommands runs only the dispatcher.
func WithoutDispatcher ¶ added in v1.0.0
func WithoutDispatcher() Option
WithoutDispatcher runs only the command processors (scale the roles independently).
type Progress ¶ added in v1.0.0
type Progress struct {
ExecID string `json:"exec_id"`
Node string `json:"node"`
Key string `json:"key"`
Generation int `json:"generation"`
Attempt int `json:"attempt"`
// Seq counts the messages of one job attempt from 1: a gap means one was
// lost (delivery is best effort).
Seq int64 `json:"seq"`
Time time.Time `json:"time"`
Data json.RawMessage `json:"data,omitempty"`
}
Progress is an intermediate result a worker published while running a node (worker.Job.Progress). It is never stored: only listeners receive it.
type ScheduleInfo ¶ added in v1.0.0
type ScheduleInfo struct {
Name string `json:"name"`
Cron string `json:"cron"`
TimeZone string `json:"time_zone,omitempty"`
Flow string `json:"flow"`
Version string `json:"version,omitempty"`
Input json.RawMessage `json:"input,omitempty"`
}
ScheduleInfo describes an installed schedule.
type ScheduleOption ¶ added in v1.0.0
type ScheduleOption func(*scheduleOpts)
ScheduleOption configures Schedule.
func ScheduleTimeZone ¶ added in v1.0.0
func ScheduleTimeZone(tz string) ScheduleOption
ScheduleTimeZone evaluates the cron expression in an IANA time zone.
func ScheduleVersion ¶ added in v1.0.0
func ScheduleVersion(hash string) ScheduleOption
ScheduleVersion pins the flow version started by the schedule.
type SignalOption ¶ added in v1.0.0
type SignalOption func(*string)
SignalOption configures Signal.
func WithSignalID ¶ added in v1.0.0
func WithSignalID(id string) SignalOption
WithSignalID sets the signal id: delivering the same id twice is idempotent (client retries after an ambiguous publish).
type StartOption ¶ added in v1.0.0
type StartOption func(*startOpts)
StartOption configures Start.
func WithExecutionID ¶ added in v1.0.0
func WithExecutionID(id string) StartOption
WithExecutionID sets the execution id: Start becomes idempotent on it (a second Start with the same id returns it without starting anything, I-03).
func WithTraceparent ¶ added in v1.0.0
func WithTraceparent(tp string) StartOption
WithTraceparent propagates a W3C traceparent to every event, job and command derived from this one.
func WithVersion ¶ added in v1.0.0
func WithVersion(hash string) StartOption
WithVersion pins a flow version hash instead of the latest.
type Store ¶ added in v1.0.0
type Store struct {
// contains filtered or unexported fields
}
Store is a namespaced key-value store for application data that outlives executions (LangGraph Store). Namespaces and keys are tokens. Worker jobs reach the same store through worker.Job.Store.
func (*Store) Get ¶ added in v1.0.0
Get returns the value under ns/key, ErrNotFound when there is none.
type Summary ¶ added in v1.0.0
type Summary = projection.Summary
Summary is the indexed view of an execution (List).
type UpdateOption ¶ added in v1.0.0
type UpdateOption func(*string)
UpdateOption configures Update.
func WithUpdateID ¶ added in v1.0.0
func WithUpdateID(id string) UpdateOption
WithUpdateID sets the update id: the same id is applied once, however often it is sent (retry an ambiguous update with the same id).
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
packtrail
command
Command packtrail is the command-line interface: run an engine, register and validate flows, start, signal, resume, cancel, inspect, watch, fork and rerun executions, manage schedules and dead letters.
|
Command packtrail is the command-line interface: run an engine, register and validate flows, start, signal, resume, cancel, inspect, watch, fork and rerun executions, manage schedules and dead letters. |
|
packtrail-ui
command
Command packtrail-ui is the debugging dashboard: execution list, flow graph coloured by node state, the event timeline with the state at any sequence (time travel), and actions — signal, resume, cancel, fork, rerun, dead-letter redrive.
|
Command packtrail-ui is the debugging dashboard: execution list, flow graph coloured by node state, the event timeline with the state at any sequence (time travel), and actions — signal, resume, cancel, fork, rerun, dead-letter redrive. |
|
Package event defines packtrail's event types.
|
Package event defines packtrail's event types. |
|
examples
|
|
|
agentloop
command
Example agentloop: the shape of a tool-using agent, built from generic parts — packtrail knows nothing about LLMs.
|
Example agentloop: the shape of a tool-using agent, built from generic parts — packtrail knows nothing about LLMs. |
|
approval
command
Example approval: human in the loop, two ways.
|
Example approval: human in the loop, two ways. |
|
events
command
Example events: executions started by time and by messages.
|
Example events: executions started by time and by messages. |
|
hello
command
Example hello: the smallest packtrail program.
|
Example hello: the smallest packtrail program. |
|
internal/devserver
Package devserver gives the examples a NATS connection to the server named by $NATS_URL (default nats://127.0.0.1:4222), which must have JetStream enabled.
|
Package devserver gives the examples a NATS connection to the server named by $NATS_URL (default nats://127.0.0.1:4222), which must have JetStream enabled. |
|
internal/exutil
Package exutil holds the few lines every example repeats.
|
Package exutil holds the few lines every example repeats. |
|
mapreduce
command
Example mapreduce: a dynamic fan-out over a list computed at run time.
|
Example mapreduce: a dynamic fan-out over a list computed at run time. |
|
research
command
Example research: parallel branches writing to shared state.
|
Example research: parallel branches writing to shared state. |
|
resilience
command
Example resilience: what happens when workers misbehave.
|
Example resilience: what happens when workers misbehave. |
|
subflow
command
Example subflow: composing flows.
|
Example subflow: composing flows. |
|
timetravel
command
Example timetravel: the event log as a debugging tool.
|
Example timetravel: the event log as a debugging tool. |
|
Package flow defines packtrail flow definitions: a declarative graph of nodes (task, choice, fanout, join, await, map, subflow) plus the typed state channels the nodes write to.
|
Package flow defines packtrail flow definitions: a declarative graph of nodes (task, choice, fanout, join, await, map, subflow) plus the typed state channels the nodes write to. |
|
internal
|
|
|
acceptance
Package acceptance is packtrail's black-box acceptance suite: every test drives a real engine, real workers and a real embedded nats-server through the public API only, with fault injection (engine kill and restart, NATS restart, duplicate and reordered completions).
|
Package acceptance is packtrail's black-box acceptance suite: every test drives a real engine, real workers and a real embedded nats-server through the public API only, with fault injection (engine kill and restart, NATS restart, duplicate and reordered completions). |
|
apierr
Package apierr holds the sentinel errors shared by the public packages, so errors.Is matches them whichever package returned them (a store read by a Client or by a worker job).
|
Package apierr holds the sentinel errors shared by the public packages, so errors.Is matches them whichever package returned them (a store read by a Client or by a worker job). |
|
blob
Package blob implements the claim-check: a message body larger than the threshold is stored in the blobs object store and the message carries only its name in the Pt-Blob header.
|
Package blob implements the claim-check: a message body larger than the threshold is stored in the blobs object store and the message carries only its name in the Pt-Blob header. |
|
cmd
Package cmd defines the commands that drive an execution.
|
Package cmd defines the commands that drive an execution. |
|
conformance
Package conformance is the worker-protocol conformance suite.
|
Package conformance is the worker-protocol conformance suite. |
|
consume
Package consume runs a JetStream pull consumer with packtrail's lifecycle: optional pinned priority group (one active consumer per partition with managed failover), bounded concurrency, panic isolation and a graceful drain on shutdown — in-flight handlers keep running under a context detached from the shutdown signal and are only cancelled when the drain budget is exhausted (I-15).
|
Package consume runs a JetStream pull consumer with packtrail's lifecycle: optional pinned priority group (one active consumer per partition with managed failover), bounded concurrency, panic isolation and a graceful drain on shutdown — in-flight handlers keep running under a context detached from the shutdown signal and are only cancelled when the drain budget is exhausted (I-15). |
|
dispatch
Package dispatch is the projection that turns events into side effects.
|
Package dispatch is the projection that turns events into side effects. |
|
engine
Package engine processes commands: for each partition of the command stream it loads the execution state (cache, or snapshot + tail), decides the events with the pure fold, appends them with optimistic concurrency and acks the command.
|
Package engine processes commands: for each partition of the command stream it loads the execution state (cache, or snapshot + tail), decides the events with the pure fold, appends them with optimistic concurrency and acks the command. |
|
eventlog
Package eventlog appends to and reads an execution's event log: the subject <ns>.ev.<partition>.<exec> of the events stream.
|
Package eventlog appends to and reads an execution's event log: the subject <ns>.ev.<partition>.<exec> of the events stream. |
|
expr
Package expr compiles and evaluates the expressions used by flow definitions: choice predicates (`when:`), map sources (`over:`), subflow inputs, search attributes and concurrency keys.
|
Package expr compiles and evaluates the expressions used by flow definitions: choice predicates (`when:`), map sources (`over:`), subflow inputs, search attributes and concurrency keys. |
|
fold
Package fold is the pure heart of packtrail: State is the projection of an execution's events, Apply folds one event into it, and Decide turns a command into the events it produces.
|
Package fold is the pure heart of packtrail: State is the projection of an execution's events, Apply folds one event into it, and Decide turns a command into the events it produces. |
|
infra
Package infra holds the NATS handles shared by every packtrail component — connection, JetStream context, resource names, partition count — and the provisioning of the streams, buckets and object stores they use.
|
Package infra holds the NATS handles shared by every packtrail component — connection, JetStream context, resource names, partition count — and the provisioning of the streams, buckets and object stores they use. |
|
loader
Package loader rebuilds execution states: snapshot + tail of the log, the flow definition the execution is bound to, and archived executions.
|
Package loader rebuilds execution states: snapshot + tail of the log, the flow definition the execution is bound to, and archived executions. |
|
metrics
Package metrics counts what the engine does, without any metrics library: the embedding application exports the snapshot however it likes.
|
Package metrics counts what the engine does, without any metrics library: the embedding application exports the snapshot however it likes. |
|
names
Package names centralises every NATS resource name packtrail uses — streams, KV buckets, object stores, subjects and durable consumer names — derived from a single namespace prefix, plus the validation rules for every identifier that ends up as a NATS subject token or KV key segment.
|
Package names centralises every NATS resource name packtrail uses — streams, KV buckets, object stores, subjects and durable consumer names — derived from a single namespace prefix, plus the validation rules for every identifier that ends up as a NATS subject token or KV key segment. |
|
natstest
Package natstest starts an embedded, in-process nats-server with JetStream enabled for use in tests.
|
Package natstest starts an embedded, in-process nats-server with JetStream enabled for use in tests. |
|
projection
Package projection maintains the visibility index: a KV projection of every execution's summary plus membership keys by status, flow and declared search attribute, so List/Query never scan the event stream.
|
Package projection maintains the visibility index: a KV projection of every execution's summary plus membership keys by status, flow and declared search attribute, so List/Query never scan the event stream. |
|
ready
Package ready reports whether a process's consumer loops are all pulling, for the run in progress: a readiness probe must not see a run that ended.
|
Package ready reports whether a process's consumer loops are all pulling, for the run in progress: a readiness probe must not see a run that ended. |
|
registry
Package registry stores flow definitions immutably in KV: key "<name>.<hash>" holds the definition, "<name>.latest" the hash of the most recently registered version.
|
Package registry stores flow definitions immutably in KV: key "<name>.<hash>" holds the definition, "<name>.latest" the hash of the most recently registered version. |
|
sched
Package sched holds packtrail's use of JetStream message scheduling: the validator for cron expressions (so a typo fails at registration instead of inside the engine) and the header set for durable one-shot timers and cron schedules.
|
Package sched holds packtrail's use of JetStream message scheduling: the validator for cron expressions (so a typo fails at registration instead of inside the engine) and the header set for durable one-shot timers and cron schedules. |
|
snapshot
Package snapshot stores periodic snapshots of execution states in KV: a cache that lets a state be rebuilt from the snapshot plus the tail of the log instead of the whole log.
|
Package snapshot stores periodic snapshots of execution states in KV: a cache that lets a state be rebuilt from the snapshot plus the tail of the log instead of the whole log. |
|
statecache
Package statecache is a bounded in-memory cache of folded execution states.
|
Package statecache is a bounded in-memory cache of folded execution states. |
|
store
Package store is the long-term key-value store for application data that outlives executions, shared by clients and worker jobs.
|
Package store is the long-term key-value store for application data that outlives executions, shared by clients and worker jobs. |
|
wire
Package wire holds the message formats shared by the engine and the SDKs beyond commands and events: worker jobs, dead letters and cache entries, plus the publish helpers that apply the claim-check and deduplication ids.
|
Package wire holds the message formats shared by the engine and the SDKs beyond commands and events: worker jobs, dead letters and cache entries, plus the publish helpers that apply the claim-check and deduplication ids. |
|
Package packtrailtest runs an embedded, in-process nats-server with JetStream enabled, for testing applications built on packtrail.
|
Package packtrailtest runs an embedded, in-process nats-server with JetStream enabled, for testing applications built on packtrail. |
|
Package worker is the Go SDK for packtrail workers.
|
Package worker is the Go SDK for packtrail workers. |