consume

package
v1.0.89 Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package consume is the consume use case: it turns a request plus a compiled catalog entry into one immutable decision, renders that decision for dry-run, and executes the very same decision for a real run. Deciding is free of external writes; every write happens behind Execute.

Index

Constants

View Source
const (
	StatusReady   = "ready"
	StatusUnknown = "unknown"
	StatusBlocked = "blocked"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Cleanup

type Cleanup = func() error

Cleanup undoes a strategy's Apply; the runtime host invokes it when this consumer is the last one for its scope.

type Decision

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

Decision is the single-step consume decision: the classified result of one request against one compiled entry. Fields are unexported and deep-copied at construction; renderers read it through View.

func (*Decision) NormalizedParams

func (d *Decision) NormalizedParams() map[string]string

NormalizedParams returns a copy of the decision's validated, normalized parameters — what a real run must consume so normalization stays a once-per-consumer event.

func (*Decision) View

func (d *Decision) View() DecisionView

View returns a deep-copied, exported view of the decision — the only way renderers and other packages read it. Mutating the view never touches the decision.

type DecisionView

type DecisionView struct {
	EventKey      string
	Domain        string
	Identity      string
	Status        string
	Params        map[string]string
	Scope         string
	Preconditions []PreconditionView
	Preparation   *PreparationView
	WouldRead     []string
	WouldWrite    []string
}

DecisionView is the exported render model of a Decision.

type ExecutionContext

type ExecutionContext struct {
	API processing.APIClient
}

ExecutionContext carries the per-request dependencies a strategy may use during Apply. Strategies hold no clients of their own: the caller resolves identity first and injects exactly one API surface for this run.

type IdentityResolver

type IdentityResolver interface {
	Resolve(ctx context.Context, entry *catalog.Entry) (string, error)
}

IdentityResolver resolves the effective identity for a run and verifies its credentials are usable. Implementations live with the command wiring.

type Precondition

type Precondition struct {
	Name     string
	Status   PreconditionStatus
	Detail   string
	BlockErr error
}

Precondition is one read-only preflight finding. BlockErr carries the exact error a real run would return, so the refusal is identical whether or not a decision was rendered first.

type PreconditionStatus

type PreconditionStatus string
const (
	// PreconditionOK: the read-only check passed.
	PreconditionOK PreconditionStatus = "ok"
	// PreconditionUnknown: a weak dependency could not answer. Real execution
	// proceeds (matching the long-standing degrade-and-continue behavior);
	// dry-run reports the fact instead of pretending readiness.
	PreconditionUnknown PreconditionStatus = "unknown"
	// PreconditionBlocked: the check found a state that makes a real run
	// refuse to start. Execution returns the blocking error; dry-run renders it.
	PreconditionBlocked PreconditionStatus = "blocked"
)

type PreconditionView

type PreconditionView struct {
	Name   string
	Status string
	Detail string
	// Subtype classifies the failure the way the error envelope does, which is
	// what callers are told to branch on.
	Subtype string
	// Hint is the recovery action, verbatim from the error that blocked.
	Hint string
	// MissingScopes lists the scopes to grant, when that is what is missing.
	MissingScopes []string
}

PreconditionView is the render model of one precondition. Beyond the human sentence in Detail it carries the machine-readable half of the failure, so a caller previewing a consume gets the same recovery information a real run would put in its error envelope instead of having to parse prose.

type PreflightReader

type PreflightReader interface {
	Read(ctx context.Context, entry *catalog.Entry, identity string) ([]Precondition, error)
}

PreflightReader performs the read-only preflight checks and reports each as a precondition. It never mutates remote or local state.

type PreparationDecision

type PreparationDecision struct {
	Strategy  catalog.StrategyRef
	Condition string
	Action    string
}

PreparationDecision is the serializable preview of what preparation would do. It is conditional by design: whether it actually runs is decided by the delivery handshake (first consumer for the scope), never at decide time.

type PreparationStrategy

type PreparationStrategy interface {
	Decide(ctx context.Context, in PreparedConsume) (PreparationDecision, error)
	Apply(ctx context.Context, d PreparationDecision, in PreparedConsume, ec ExecutionContext) (Cleanup, error)
}

PreparationStrategy separates deciding what preparation would do (no external writes) from doing it (the only write entry point).

type PreparationView

type PreparationView struct {
	Strategy  string
	Condition string
	Action    string
}

type PrepareFunc

type PrepareFunc = func(ctx context.Context) (Cleanup, error)

PrepareFunc is what Execute hands the stream host: invoked exactly when the delivery handshake says this consumer is first for its scope.

type PreparedConsume

type PreparedConsume struct {
	Entry  *catalog.Entry
	Params map[string]string
}

PreparedConsume is the classified input a strategy decides and applies for.

type Registry

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

Registry holds the executable strategies and doubles as the catalog's StrategySet, so the compiler validates references against exactly the set that will execute.

func DefaultRegistry

func DefaultRegistry() *Registry

DefaultRegistry returns the strategies this build ships: no preparation, and the wrapper over a declaration's PreConsume hook.

func (*Registry) Has

func (r *Registry) Has(ref catalog.StrategyRef) bool

type Request

type Request struct {
	EventKey  string
	Params    map[string]string
	JQExpr    string
	OutputDir string
	DryRun    bool
	MaxEvents int
	Timeout   time.Duration
	IsTTY     bool
}

Request carries the caller's consume inputs, already parsed from flags.

type Service

type Service struct {
	Strategies *Registry
	Identity   IdentityResolver
	Preflight  PreflightReader
}

Service orchestrates the consume use case in a fixed order: decide first, render or execute the same decision second.

func (*Service) Decide

func (s *Service) Decide(ctx context.Context, entry *catalog.Entry, req Request, api ExecutionContext) (*Decision, error)

Decide classifies one request against one compiled entry. It performs no external writes: parameter normalization works on a copy, and every remote interaction is a read-only preflight.

func (*Service) Execute

func (s *Service) Execute(ctx context.Context, entry *catalog.Entry, d *Decision, runner StreamRunner, ec ExecutionContext) error

Execute runs the decision for real. A blocked decision returns the exact error its preflight produced; an unknown decision proceeds — weak dependencies degrade with a stderr note, they do not block, matching the behavior consumers have always had.

type StreamRunner

type StreamRunner interface {
	Run(ctx context.Context, prepare PrepareFunc) error
}

StreamRunner runs the delivery stream for an already-decided consume. The production implementation wraps the runtime host; tests substitute spies.

Jump to

Keyboard shortcuts

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