pipeline

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: 13 Imported by: 0

Documentation

Overview

Package pipeline implements stage-based execution for stream pipelines. Operators are grouped into stages that execute as direct function calls; bounded edges between stages provide backpressure: a full edge blocks the upstream stage, and the pressure propagates back to the source.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SampleEdges

func SampleEdges(stop <-chan struct{}, edges []*Edge)

SampleEdges starts the edge gauge sampler in a goroutine; it stops when stop is closed.

Types

type ChannelStage

type ChannelStage struct {
	Op        operator.Operator
	Label     string
	StageName string // unique name assigned by the planner
}

ChannelStage runs a single channel-based operator that is neither a SingleProcessor nor part of a keyed stage (e.g. Window or Reduce used without KeyBy). It preserves the old per-operator execution model for that operator alone.

func (*ChannelStage) Name

func (s *ChannelStage) Name() string

func (*ChannelStage) Run

func (s *ChannelStage) Run(runCtx, hardCtx context.Context, in <-chan types.Record, out chan<- types.Record) error

type Edge

type Edge struct {
	Name string
	Ch   chan types.Record
}

Edge is a bounded channel connecting two stages. A full edge blocks the upstream stage — that blocking is the backpressure mechanism.

func NewEdge

func NewEdge(name string, capacity int) *Edge

NewEdge creates an edge with the given name and capacity.

type KeyedStage

type KeyedStage struct {
	KeyBy *operator.KeyByOperator

	// StageName is the unique name assigned by the planner (metrics label).
	StageName string
	// contains filtered or unexported fields
}

KeyedStage executes stateful operators (Window, Reduce) with keyed parallelism:

          ┌── worker 0: Op₀_clone → Op₁_clone ──┐
in ── Router ── worker 1: Op₀_clone → Op₁_clone ──┼── alignedMerge → out
          └── worker N: Op₀_clone → Op₁_clone ──┘

Each worker owns a clone of every stateful operator with an isolated state backend. The router hash-dispatches data records (same key → same worker) and broadcasts barriers/watermarks to all workers; the merge emits each marker exactly once after all workers deliver it (C1).

func NewKeyedStage

func NewKeyedStage(kb *operator.KeyByOperator, ops []operator.Operator, hooks StageHooks) (*KeyedStage, error)

NewKeyedStage clones the stateful operator chain once per partition. hooks.OnClone registers every clone for checkpoint restore and returns its global index; hooks.OnSnapshot receives each clone's state captured synchronously when a barrier passes through it — the race-free snapshot point (snapshotting later, at the end of the pipeline, races with the clone processing post-barrier records); hooks.StateBackendFor injects each clone's state backend, keyed by the same "worker-<idx>" owner ID the checkpoint format uses.

func (*KeyedStage) Name

func (s *KeyedStage) Name() string

func (*KeyedStage) Run

func (s *KeyedStage) Run(runCtx, hardCtx context.Context, in <-chan types.Record, out chan<- types.Record) error

type PlanConfig

type PlanConfig struct {
	Source    source.Source
	Operators []operator.Operator
	Labels    []string // metric label per operator, aligned with Operators
	Sink      sink.Sink

	// DrainTimeout bounds the source offset flush on shutdown.
	DrainTimeout time.Duration

	// StageHooks are forwarded to the stages the planner builds.
	StageHooks
}

PlanConfig is the input to BuildPlan.

type SinkStage

type SinkStage struct {
	Sink sink.Sink

	// OnBarrier, when set (uncoordinated checkpointing), is invoked
	// for each barrier only after the sink has drained every record
	// ahead of it — so a checkpoint is never durable for records the
	// sink never received. Coordinated (exactly-once) pipelines leave
	// this nil; the sink itself acknowledges barriers there.
	OnBarrier func(checkpointID string)
}

SinkStage wraps a sink.Sink as the last stage of a plan.

func (*SinkStage) Name

func (s *SinkStage) Name() string

func (*SinkStage) Run

func (s *SinkStage) Run(runCtx, hardCtx context.Context, in <-chan types.Record, _ chan<- types.Record) error

Run pumps records from the input edge into the sink. The sink gets hardCtx so it keeps draining through graceful shutdown and is only interrupted by the shutdown timeout (C3).

type SourceStage

type SourceStage struct {
	Source source.Source

	// DrainTimeout bounds the source's offset flush on shutdown.
	DrainTimeout time.Duration
}

SourceStage wraps a source.Source as the first stage of a plan.

func (*SourceStage) Name

func (s *SourceStage) Name() string

func (*SourceStage) Run

func (s *SourceStage) Run(runCtx, hardCtx context.Context, _ <-chan types.Record, out chan<- types.Record) error

Run starts the source and forwards its records to the output edge. Source errors are reported via metrics/log but do not fail the pipeline (parity with previous behavior — the stream simply ends).

type Stage

type Stage interface {
	Name() string
	Run(runCtx, hardCtx context.Context, in <-chan types.Record, out chan<- types.Record) error
}

Stage is one execution unit of a pipeline. Stages run concurrently, connected by bounded edges.

Contract:

  • Run consumes in until it is closed and closes out before returning (C2: the writer owns the close). The wiring never closes edges.
  • runCtx is the caller's context: only the source stage reacts to it, by stopping production. Downstream stages drain via the cascading channel closes that follow (C3).
  • hardCtx aborts blocked sends/reads; it fires only on shutdown-timeout expiry or a fatal error in another stage.

func BuildPlan

func BuildPlan(cfg PlanConfig) ([]Stage, error)

BuildPlan groups the flat operator list into execution stages:

  • consecutive stateless operators (SingleProcessor) with the same parallelism share one StatelessStage
  • a KeyBy router starts a KeyedStage that consumes the following Cloneable (stateful) operators
  • any other channel-based operator gets its own ChannelStage
  • SourceStage and SinkStage bracket the plan

The returned stages are wired with one bounded edge between each consecutive pair.

type StageHooks

type StageHooks struct {
	// OnClone is called for every stateful operator clone a keyed
	// stage creates, so the caller can register it for checkpointing.
	// It returns the clone's global worker index ("worker-<idx>" in
	// checkpoint data).
	OnClone func(operator.Operator) int

	// OnSnapshot receives operator state captured synchronously when
	// a barrier passes through a stateful operator (the race-free
	// snapshot point). key is the checkpoint-data key ("worker-<idx>"
	// or "op-<idx>").
	OnSnapshot func(checkpointID, key string, snapshot []byte)

	// StateBackendFor creates the state backend for a stateful
	// operator instance, keyed by its owner ID ("op-<i>" or
	// "worker-<idx>"). Nil means operators keep their self-created
	// default (in-memory) backends.
	StateBackendFor func(ownerID string) (state.StateBackend, error)

	// NativeStateDir returns the directory a Checkpointable backend
	// should hard-link its barrier-time checkpoint into, for a given
	// (checkpoint ID, owner). Nil when checkpointing is off or the
	// storage has no state directory support.
	NativeStateDir func(checkpointID, ownerID string) string
}

StageHooks are engine callbacks wired into stateful stages.

type StatelessStage

type StatelessStage struct {
	StageName   string
	Ops         []operator.Operator // every op must implement operator.SingleProcessor
	Labels      []string            // metric label per op, aligned with Ops
	Parallelism int
}

StatelessStage executes a chain of stateless operators (Map, Filter, FlatMap, Process) as direct function calls — no channels between operators. With Parallelism > 1, N workers share the input via a round-robin dispatcher; barriers and watermarks are broadcast to all workers and re-aligned at the merge (C1). Record order across workers is not preserved when Parallelism > 1.

func (*StatelessStage) Name

func (s *StatelessStage) Name() string

func (*StatelessStage) Run

func (s *StatelessStage) Run(runCtx, hardCtx context.Context, in <-chan types.Record, out chan<- types.Record) error

Jump to

Keyboard shortcuts

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