jobagent

package
v0.7.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 19, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package jobagent supervises a single Mailer job in-process and exposes its lifecycle over HTTP. One agent owns one *mailer.StreamExecutionEnv: it runs Execute in a goroutine, tracks lifecycle transitions, serves /state, /describe, /metrics, /healthz, and translates POST /cancel into a graceful context cancellation.

This is the control contract every runner embeds (see the mailer-runner binary and the job-orchestration plan, phase P1). It adds no container or scheduling concerns — those live in the separate control plane.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Agent

type Agent struct {
	// contains filtered or unexported fields
}

Agent supervises one job. It is safe for concurrent use: State/Cancel may be called from HTTP handlers while Run executes on another goroutine.

func New

func New(env *mailer.StreamExecutionEnv) *Agent

New creates an agent that will run the given configured environment. The env must already have its source, sink, and any operators wired (e.g. from the workflow compiler); the agent does not build pipelines.

func (*Agent) Cancel

func (a *Agent) Cancel()

Cancel requests a graceful shutdown. It is idempotent and a no-op once the job has reached a terminal phase. The pipeline drains in-flight records and takes a final checkpoint before Run returns.

func (*Agent) DescribeJSON

func (a *Agent) DescribeJSON() string

DescribeJSON returns the pipeline topology as indented JSON.

func (*Agent) Handler

func (a *Agent) Handler() http.Handler

Handler returns the agent's HTTP surface. Routes use Go 1.22+ method patterns so wrong-method requests get 405 automatically.

GET  /healthz    liveness + current phase
GET  /state      lifecycle snapshot (JSON State)
GET  /describe   pipeline topology (env.DescribeJSON)
GET  /metrics    Prometheus exposition
POST /cancel     request graceful shutdown
POST /savepoint  stop-with-savepoint (?label=<name>)

func (*Agent) RequestSavepoint

func (a *Agent) RequestSavepoint(label string) bool

RequestSavepoint asks for a stop-with-savepoint: the job drains and writes its final checkpoint (like Cancel), and the label is recorded so the runner can promote that checkpoint to a named savepoint once Run returns. It is a no-op once the job is terminal; returns whether the request was accepted.

func (*Agent) Run

func (a *Agent) Run(ctx context.Context) error

Run executes the job to completion, blocking until it finishes, fails, or a cancel drains it. It registers the checkpoint listener, moves the phase to Running, then calls Execute. The returned error is Execute's error (nil on a clean finish or a completed cancel). Run is intended to be called once.

func (*Agent) SavepointRequest

func (a *Agent) SavepointRequest() (label string, requested bool)

SavepointRequest reports whether a savepoint was requested and its label. The runner reads this after Run returns to decide whether to promote the final checkpoint.

func (*Agent) Serve

func (a *Agent) Serve(ctx context.Context, addr string) error

Serve runs the agent's HTTP server on addr until ctx is cancelled, then shuts it down gracefully. It blocks; run it in its own goroutine alongside Run. Returns nil on a clean ctx-driven shutdown.

func (*Agent) State

func (a *Agent) State() State

State returns a snapshot, refreshing the live-computed fields (uptime and record counts) at call time.

type Phase

type Phase string

Phase is the coarse lifecycle state of a supervised job. It only ever moves forward: Starting → Running → (Cancelling) → Finished | Failed.

const (
	// PhaseStarting is set from construction until Execute is entered.
	PhaseStarting Phase = "starting"
	// PhaseRunning means Execute is in progress.
	PhaseRunning Phase = "running"
	// PhaseCancelling means a cancel was requested and the pipeline is
	// draining; it still ends in Finished (clean drain) or Failed.
	PhaseCancelling Phase = "cancelling"
	// PhaseFinished is a clean terminal state: the source drained or a
	// cancel completed its graceful shutdown without error.
	PhaseFinished Phase = "finished"
	// PhaseFailed is a terminal state: Execute returned a non-cancel error.
	PhaseFailed Phase = "failed"
)

func (Phase) Terminal

func (p Phase) Terminal() bool

Terminal reports whether the phase is an end state.

type State

type State struct {
	Phase      Phase     `json:"phase"`
	StartedAt  time.Time `json:"startedAt"`
	Uptime     string    `json:"uptime"`
	RecordsIn  int64     `json:"recordsIn"`
	RecordsOut int64     `json:"recordsOut"`

	// CurrentCheckpointID is the ID of the most recently completed
	// checkpoint, empty until the first one completes.
	CurrentCheckpointID string `json:"currentCheckpointId,omitempty"`
	// LastCheckpointAt is when the agent observed that checkpoint
	// complete (nil until the first one).
	LastCheckpointAt *time.Time `json:"lastCheckpointAt,omitempty"`

	// LastError is the terminal error message when Phase is Failed.
	LastError string `json:"lastError,omitempty"`
}

State is a point-in-time snapshot of a job, returned by GET /state. Record counts are read from the process Prometheus counters at snapshot time (one job per process, so the cumulative counters are the job's totals); checkpoint fields are populated by the engine checkpoint listener.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL