Documentation
¶
Overview ¶
Package bindings is backplane's side of bindings (§7.1) and rules (§8.1): the model, validation against the manifests, versions in PostgreSQL and the console's BindingService, RuleService and WiringService.
A binding implements a hook ("<service>.<Hook>") with steps — calls of activities of any service — and a result; a rule runs the same steps on an event. Values are JSON trees whose strings are CEL expressions over JSON values: `req` (the hook's input) or `event` and `meta` (a rule's event and its CloudEvents attributes), the output of every step by its name, and `steps.<name>.skipped`.
For the executor and the rules engine the package offers:
- Manager.Active / Manager.ActiveRules: what is in force now;
- Compile: a definition checked against a Catalog into a *Program — steps with their dependencies and groups, options resolved from the manifests, expressions compiled; JSON-serializable, so a workflow receives it as input;
- Program's evaluation (Start, Bind, When, Input, UndoInput, Result, Match, Eval): pure and deterministic — no clock, no randomness, no I/O, map iteration in key order — so it runs inside workflow code.
Index ¶
- Constants
- Variables
- func FileRuleID(name string) uuid.UUID
- func IsFullName(s string) bool
- func IsIdent(s string) bool
- func Pointer(keys ...string) string
- func RenameBinding(b Binding, from, to string) (Binding, []Violation)
- func RenameRule(rule Rule, from, to string) (Rule, []Violation)
- func SplitName(full string) (string, string)
- func ViolationsPB(vs []Violation) []*consolev1.Violation
- type Analysis
- type Base
- type Binding
- type BindingAPI
- func (a BindingAPI) DeleteBinding(ctx context.Context, req *consolev1.DeleteBindingRequest) (*consolev1.DeleteBindingResponse, error)
- func (a BindingAPI) GetBinding(ctx context.Context, req *consolev1.GetBindingRequest) (*consolev1.GetBindingResponse, error)
- func (a BindingAPI) ListBindingVersions(ctx context.Context, req *consolev1.ListBindingVersionsRequest) (*consolev1.ListBindingVersionsResponse, error)
- func (a BindingAPI) ListBindings(ctx context.Context, req *consolev1.ListBindingsRequest) (*consolev1.ListBindingsResponse, error)
- func (a BindingAPI) RollbackBinding(ctx context.Context, req *consolev1.RollbackBindingRequest) (*consolev1.RollbackBindingResponse, error)
- func (a BindingAPI) SaveBinding(ctx context.Context, req *consolev1.SaveBindingRequest) (*consolev1.SaveBindingResponse, error)
- func (a BindingAPI) ValidateBinding(_ context.Context, req *consolev1.ValidateBindingRequest) (*consolev1.ValidateBindingResponse, error)
- func (a BindingAPI) WatchBindings(req *consolev1.WatchBindingsRequest, ...) error
- type BindingVersion
- type CallLabel
- type Catalog
- type Defaulter
- type Defaults
- type EvalError
- type Field
- type Files
- type ForEachPlan
- type InvalidError
- type ItemError
- type Kind
- type Manager
- func (m *Manager) Active(ctx context.Context, hook string) (Binding, int64, error)
- func (m *Manager) ActiveRules(ctx context.Context) ([]RuleEntry, error)
- func (m *Manager) BindingAPI() BindingAPI
- func (m *Manager) Catalog() (Catalog, error)
- func (m *Manager) Changes(ctx context.Context) <-chan struct{}
- func (m *Manager) Current(ctx context.Context, hook string) (BindingVersion, bool, error)
- func (m *Manager) CurrentAll(ctx context.Context) ([]BindingVersion, error)
- func (m *Manager) Defaults() Defaults
- func (m *Manager) Delete(ctx context.Context, hook, comment string, base Base) (BindingVersion, error)
- func (m *Manager) DeleteRule(ctx context.Context, id uuid.UUID, comment string, base Base) (RuleVersion, error)
- func (m *Manager) HookBindings(ctx context.Context, service string) ([]*consolev1.HookBinding, error)
- func (m *Manager) PauseRule(ctx context.Context, id uuid.UUID, paused bool, base Base) (RuleEntry, error)
- func (m *Manager) Register(r grpc.ServiceRegistrar)
- func (m *Manager) Rollback(ctx context.Context, hook string, version int64, comment string, base Base) (Saved, error)
- func (m *Manager) RollbackRule(ctx context.Context, id uuid.UUID, version int64, comment string, base Base) (SavedRule, error)
- func (m *Manager) Rule(ctx context.Context, id uuid.UUID) (RuleEntry, error)
- func (m *Manager) RuleAPI() RuleAPI
- func (m *Manager) RuleVersion(ctx context.Context, id uuid.UUID, version int64) (RuleVersion, error)
- func (m *Manager) RuleVersions(ctx context.Context, id uuid.UUID, before int64, size int) ([]RuleVersion, error)
- func (m *Manager) Rules(ctx context.Context) ([]RuleEntry, error)
- func (m *Manager) Save(ctx context.Context, b Binding, comment string, base Base) (Saved, error)
- func (m *Manager) SaveRule(ctx context.Context, id uuid.UUID, name string, r Rule, comment string, ...) (SavedRule, error)
- func (m *Manager) Validate(b Binding) ([]Violation, error)
- func (m *Manager) ValidateRule(name string, r Rule) ([]Violation, error)
- func (m *Manager) Version(ctx context.Context, hook string, version int64) (BindingVersion, error)
- func (m *Manager) Versions(ctx context.Context, hook string, before int64, size int) ([]BindingVersion, error)
- func (m *Manager) WiringAPI() WiringAPI
- type Manifests
- type Meta
- type Option
- type PathExpr
- type Program
- func (p *Program) Begin(item Scope) Scope
- func (p *Program) Bind(s Scope, step string, output []byte) (Scope, error)
- func (p *Program) BindItems(s Scope, step string, outputs [][]byte, failed []ItemError) (Scope, error)
- func (p *Program) Body(step string) (*Program, bool)
- func (p *Program) Eval(src string, vars map[string]any) (any, error)
- func (p *Program) Groups() [][]string
- func (p *Program) Hash() string
- func (p *Program) Input(step string, s Scope) ([]byte, error)
- func (p *Program) ItemOutput(s Scope) ([]byte, error)
- func (p *Program) ItemScope(step string, s Scope, index int, item any) (Scope, error)
- func (p *Program) Items(step string, s Scope) ([]any, error)
- func (p *Program) Kind() Kind
- func (p *Program) MarshalJSON() ([]byte, error)
- func (p *Program) Masks() *redact.Program
- func (p *Program) Match(s Scope) (bool, error)
- func (p *Program) Result(s Scope) ([]byte, error)
- func (p *Program) Runtime() consolev1.Runtime
- func (p *Program) Skip(s Scope, step string) (Scope, error)
- func (p *Program) Source() string
- func (p *Program) Spec() []byte
- func (p *Program) Start(input []byte) (Scope, error)
- func (p *Program) StartEvent(payload []byte, meta Meta) (Scope, error)
- func (p *Program) Step(name string) (StepPlan, bool)
- func (p *Program) Steps() []StepPlan
- func (p *Program) UndoInput(step string, s Scope) ([]byte, error)
- func (p *Program) UnmarshalJSON(data []byte) error
- func (p *Program) When(step string, s Scope) (bool, error)
- type Publisher
- type Range
- type Reference
- type Retry
- type Rule
- type RuleAPI
- func (a RuleAPI) DeleteRule(ctx context.Context, req *consolev1.DeleteRuleRequest) (*consolev1.DeleteRuleResponse, error)
- func (a RuleAPI) GetRule(ctx context.Context, req *consolev1.GetRuleRequest) (*consolev1.GetRuleResponse, error)
- func (a RuleAPI) ListRuleVersions(ctx context.Context, req *consolev1.ListRuleVersionsRequest) (*consolev1.ListRuleVersionsResponse, error)
- func (a RuleAPI) ListRules(ctx context.Context, req *consolev1.ListRulesRequest) (*consolev1.ListRulesResponse, error)
- func (a RuleAPI) PauseRule(ctx context.Context, req *consolev1.PauseRuleRequest) (*consolev1.PauseRuleResponse, error)
- func (a RuleAPI) ResumeRule(ctx context.Context, req *consolev1.ResumeRuleRequest) (*consolev1.ResumeRuleResponse, error)
- func (a RuleAPI) RollbackRule(ctx context.Context, req *consolev1.RollbackRuleRequest) (*consolev1.RollbackRuleResponse, error)
- func (a RuleAPI) SaveRule(ctx context.Context, req *consolev1.SaveRuleRequest) (*consolev1.SaveRuleResponse, error)
- func (a RuleAPI) ValidateRule(_ context.Context, req *consolev1.ValidateRuleRequest) (*consolev1.ValidateRuleResponse, error)
- func (a RuleAPI) WatchRules(req *consolev1.WatchRulesRequest, ...) error
- type RuleEntry
- type RuleVersion
- type Saved
- type SavedRule
- type Scope
- type Step
- type StepAnalysis
- type StepPlan
- type Value
- func (v Value) Equal(o Value) bool
- func (v Value) Expr() string
- func (v Value) Expressions(base string) []PathExpr
- func (v Value) Fields() []Field
- func (v Value) IsZero() bool
- func (v Value) Items() []Value
- func (v Value) JSON() []byte
- func (v Value) Kind() ValueKind
- func (v Value) Literal() any
- func (v Value) PB() *structpb.Value
- type ValueKind
- type ValueType
- type Violation
- type WiringAPI
- func (a WiringAPI) AnalyzeBinding(_ context.Context, req *consolev1.AnalyzeBindingRequest) (*consolev1.AnalyzeBindingResponse, error)
- func (a WiringAPI) AnalyzeRule(_ context.Context, req *consolev1.AnalyzeRuleRequest) (*consolev1.AnalyzeRuleResponse, error)
- func (a WiringAPI) GetWiringCatalog(context.Context, *consolev1.GetWiringCatalogRequest) (*consolev1.GetWiringCatalogResponse, error)
- func (a WiringAPI) RenameStep(_ context.Context, req *consolev1.RenameStepRequest) (*consolev1.RenameStepResponse, error)
Constants ¶
const ( DefaultStartToClose = 30 * time.Second DefaultAttempts = 3 DefaultInitialInterval = time.Second DefaultMaxInterval = 30 * time.Second DefaultBackoff = 2.0 )
Platform defaults of a step, below the binding's own options and the activity's manifest defaults.
const ( OnErrorFail = "fail" OnErrorContinue = "continue" // DefaultItemVar names the item without As. DefaultItemVar = "item" DefaultConcurrency = 10 MaxConcurrency = 100 DefaultMaxItems = 1000 MaxItemsLimit = 10000 )
For-each options.
const ( CodeInvalidName = "INVALID_NAME" CodeReservedName = "RESERVED_NAME" CodeUnknownHook = "UNKNOWN_HOOK" CodeUnknownEvent = "UNKNOWN_EVENT" CodeUnknownActivity = "UNKNOWN_ACTIVITY" CodeUnknownStep = "UNKNOWN_STEP" CodeCycle = "CYCLE" CodeUndoReference = "UNDO_REFERENCE" CodeCEL = "CEL_ERROR" CodeCost = "COST" CodeTypeMismatch = "TYPE_MISMATCH" CodeMissingField = "MISSING_FIELD" CodeUnknownField = "UNKNOWN_FIELD" CodeInvalidValue = "INVALID_VALUE" CodeInvalidOption = "INVALID_OPTION" // CodeRuntimeUnsupported: the step uses what the definition's runtime // does not run (undo, heartbeat or a child workflow on direct). CodeRuntimeUnsupported = "RUNTIME_UNSUPPORTED" )
Violation codes.
const ( VarReq = "req" VarEvent = "event" VarMeta = "meta" VarSteps = "steps" )
Variables every expression may see besides the steps: step names must differ from them.
const BoundPrefix = "backplane/bindings/"
BoundPrefix is where each service's bound hooks are published: BoundPrefix+<service> holds a JSON array of hook names without the service prefix. The SDK watches its own key (pkg/backplane's consul driver), so a service can skip work for a hook nobody bound.
const DefaultAuthor = "admin"
DefaultAuthor is the author of a version saved outside a console session.
const FilesAuthor = "wiring"
FilesAuthor is the author of the versions the wiring files write.
Variables ¶
var ( ErrNotSynced = errors.New("bindings: the registry has not synced with consul yet") // ErrNoBinding: the hook has no binding in force (never saved or // deleted). ErrNoBinding = errors.New("bindings: no binding") ErrNoVersion = errors.New("bindings: no such version") ErrNoRule = errors.New("bindings: no such rule") // ErrDeleted: the rule or binding is deleted already. ErrDeleted = errors.New("bindings: deleted") // ErrConflict: an edit started from a version that is no longer the // current one. ErrConflict = errors.New("bindings: changed since the edit started") // ErrManaged: the binding or rule is defined in a wiring file, which // alone changes it. ErrManaged = errors.New("bindings: managed by a wiring file") )
Errors of the Manager.
var ErrWiringFile = errors.New("bindings: wiring file")
ErrWiringFile: a wiring file is not a valid definition of bindings and rules.
Functions ¶
func FileRuleID ¶ added in v0.6.13
FileRuleID is the id of the rule a wiring file names name.
func IsFullName ¶
IsFullName reports whether s is "<service>.<Name>" (§17).
func RenameBinding ¶
RenameBinding is b with step from renamed to: its key, every `after` naming it, its editor position and every expression reading it (by the expressions' syntax trees: a string or a field of the same name stays). from is the step's id: its name, or "<for-each step>/<name>" for a step of a body (bodies nest); to is its new name. Refused: the violations say why.
func RenameRule ¶
RenameRule is RenameBinding for a rule.
func SplitName ¶
SplitName splits "<service>.<Name>" at its first dot into the service and the name.
func ViolationsPB ¶
ViolationsPB are the violations as messages.
Types ¶
type Analysis ¶
type Analysis struct {
Violations []Violation
// Steps by name.
Steps []StepAnalysis
// Types by path.
Types []ValueType
// References by path, then position.
References []Reference
// Secrets are the paths of the value nodes that carry secrets: fields
// marked secret by a schema, or computed from one. Empty until the
// definition is valid.
Secrets []string
// Runtime the definition compiled for: its own, else the catalog's
// default, else Temporal.
Runtime consolev1.Runtime
}
Analysis is a definition as the compiler sees it: its violations, the order of its steps, the type of every value and what every expression reads. Parts that do not compile are left out.
func AnalyzeBinding ¶
AnalyzeBinding checks b against the catalog and describes it.
func AnalyzeRule ¶
AnalyzeRule checks r against the catalog and describes it.
type Base ¶
type Base struct {
// contains filtered or unexported fields
}
Base is the version an edit started from. The zero Base skips the check; At(v) refuses the edit with ErrConflict when the current version is another one (0: none yet).
type Binding ¶
type Binding struct {
// Hook is the full hook name "<service>.<Hook>".
Hook string
Description string
// Steps are sorted by name: order is not significant, execution
// follows dependencies.
Steps []Step
// Result is the hook's output; zero: {}.
Result Value
// Runtime runs the binding; unspecified: the installation's default.
Runtime consolev1.Runtime
// Editor is the graph editor's layout, kept as saved; compile and
// execution ignore it.
Editor *consolev1.EditorLayout
}
Binding is the definition of a hook's binding.
func BindingFromPB ¶
func BindingFromPB(m *consolev1.BindingDefinition) Binding
BindingFromPB is the definition a message carries.
func BindingYAML ¶
BindingYAML reads a binding definition from YAML: its protojson form written as YAML, as the console edits it.
hook: hello.Greet
steps:
formatted:
activity: formatter.Format
input: {name: req.name}
result: {text: formatted.text}
func (Binding) PB ¶
func (b Binding) PB() *consolev1.BindingDefinition
PB is the definition as a message.
type BindingAPI ¶
type BindingAPI struct {
consolev1.UnimplementedBindingServiceServer
// contains filtered or unexported fields
}
BindingAPI is the Manager as backplane.console.v1.BindingService.
func (BindingAPI) DeleteBinding ¶
func (a BindingAPI) DeleteBinding( ctx context.Context, req *consolev1.DeleteBindingRequest, ) (*consolev1.DeleteBindingResponse, error)
DeleteBinding implements BindingService.
func (BindingAPI) GetBinding ¶
func (a BindingAPI) GetBinding( ctx context.Context, req *consolev1.GetBindingRequest, ) (*consolev1.GetBindingResponse, error)
GetBinding implements BindingService.
func (BindingAPI) ListBindingVersions ¶
func (a BindingAPI) ListBindingVersions( ctx context.Context, req *consolev1.ListBindingVersionsRequest, ) (*consolev1.ListBindingVersionsResponse, error)
ListBindingVersions implements BindingService.
func (BindingAPI) ListBindings ¶
func (a BindingAPI) ListBindings( ctx context.Context, req *consolev1.ListBindingsRequest, ) (*consolev1.ListBindingsResponse, error)
ListBindings implements BindingService.
func (BindingAPI) RollbackBinding ¶
func (a BindingAPI) RollbackBinding( ctx context.Context, req *consolev1.RollbackBindingRequest, ) (*consolev1.RollbackBindingResponse, error)
RollbackBinding implements BindingService.
func (BindingAPI) SaveBinding ¶
func (a BindingAPI) SaveBinding( ctx context.Context, req *consolev1.SaveBindingRequest, ) (*consolev1.SaveBindingResponse, error)
SaveBinding implements BindingService.
func (BindingAPI) ValidateBinding ¶
func (a BindingAPI) ValidateBinding( _ context.Context, req *consolev1.ValidateBindingRequest, ) (*consolev1.ValidateBindingResponse, error)
ValidateBinding implements BindingService.
func (BindingAPI) WatchBindings ¶
func (a BindingAPI) WatchBindings( req *consolev1.WatchBindingsRequest, stream grpc.ServerStreamingServer[consolev1.WatchBindingsResponse], ) error
WatchBindings implements BindingService: the list now, then again whenever it differs — a save here or on another replica, a manifest.
type BindingVersion ¶
type BindingVersion struct {
Hook string
Version int64
// Binding is the definition; zero on a tombstone.
Binding Binding
// Deleted marks a tombstone: the delete of the binding.
Deleted bool
Author string
Comment string
CreatedAt time.Time
RollbackOf int64 // 0: not a rollback
// ManagedBy is the wiring file the version came from; "" for the
// console's versions.
ManagedBy string
}
BindingVersion is one saved version of a hook's binding.
func (BindingVersion) PB ¶
func (v BindingVersion) PB() *consolev1.BindingVersion
PB is the version as a message.
type CallLabel ¶
CallLabel is a call label read back: the call is of Step, in the body of the for-each step Parent (its id: "<outer>/<inner>" in a nested body; "" at the top), for Item (the step's own, or its innermost enclosing for-each step's for a step of a body; -1: none).
func ParseCallLabel ¶
ParseCallLabel reads a call label — the envelope's step: segments "<step>" or "<step>[<item>]" joined by "." from the outermost for-each step in.
type Catalog ¶
type Catalog interface {
Hook(name string) (*backplanev1.Hook, bool)
Event(name string) (*backplanev1.Event, bool)
Activity(name string) (*backplanev1.Activity, bool)
}
Catalog resolves full names ("<service>.<Name>") to what the manifests declare. Validation and Compile see the installation through it.
func FromRegistry ¶
FromRegistry is the catalog of the latest manifest of every service in a registry snapshot (registry.Service.Latest: the highest version a live instance runs).
func WithDefaults ¶ added in v0.3.0
WithDefaults is cat with the installation's defaults.
type Defaulter ¶ added in v0.3.0
type Defaulter interface {
Defaults() Defaults
}
Defaulter is a Catalog that also carries the installation's defaults; compile reads them when it has them.
type Defaults ¶ added in v0.3.0
type Defaults struct {
// Runtime of a definition that names none; unspecified: Temporal.
Runtime consolev1.Runtime
}
Defaults are what a definition leaves to the installation.
func DefaultsOf ¶ added in v0.3.0
DefaultsOf are cat's defaults, zero when it carries none.
type EvalError ¶
type EvalError struct {
// Step is empty for the result and a rule's when.
Step string
// Place: when, input, input.<field>, undo input, output, result, event.
Place string
Err error
}
EvalError is an expression that failed on the values of a run: "transform failed at step render (input.to): no such key: x".
type Files ¶ added in v0.6.13
Files keeps the bindings and rules of a wiring directory in force: the directory is the desired state, and the console only reads what it holds.
Every *.yaml / *.yml file under the directory (dot-names skipped, so a Kubernetes ConfigMap mount works as is) holds one or more documents:
bindings:
- hook: kratos.Deliver # BindingDefinition, as the console edits it
steps: {...}
rules:
- name: welcome # the rule's identity
event: kratos.IdentityCreated
steps: {...}
A pass saves what differs from the current version as a new version managed by its file, and tombstones what a file held before and holds no more. A definition that does not compile against the manifests waits — for the services to register or for a fixed file — with the version in force untouched; a directory that does not read whole changes nothing. Replicas run it side by side: saves are conditional on the version read, so they converge.
type ForEachPlan ¶
type ForEachPlan struct {
// Item names the item variable; its position is Item+"Index".
Item string `json:"item"`
// Concurrency bounds the items in flight.
Concurrency int `json:"concurrency"`
// Continue: failed items are collected, the step succeeds; else the
// first failure fails it.
Continue bool `json:"continue,omitempty"`
// MaxItems bounds the items: more fails the step.
MaxItems int `json:"max_items"`
// Steps: the body is a sub-flow (Program.Body), else the activity.
Steps bool `json:"steps,omitempty"`
}
ForEachPlan is how a for-each step runs its items.
type InvalidError ¶
type InvalidError struct{ Violations []Violation }
InvalidError is a definition that does not compile: the violations say why.
func (*InvalidError) Error ¶
func (e *InvalidError) Error() string
type Kind ¶
type Kind int
Kind is what a program implements.
const ( // KindBinding implements a hook: input `req`, a result. KindBinding Kind = iota + 1 // KindRule reacts to an event: input `event` and `meta`, a filter, no // result. KindRule // KindBody is a for-each step's sub-flow (Program.Body): it runs in the // scope of an item, its result is the item's output. KindBody )
Kinds of programs.
type Manager ¶
Manager keeps bindings and rules: versions in PostgreSQL, validation against the registry's latest manifests, the console's BindingService and RuleService, and Changes for the executor and the rules engine. It holds state and a goroutine: share it by pointer.
func New ¶
func New(parent deps.Scope, st deps.Dependency[*store.Store], src registry.Source, opts ...Option) *Manager
New creates the component under parent: versions in st, manifests from src.
func (*Manager) Active ¶
Active is the binding in force for the hook and its version: ErrNoBinding when never saved or deleted. The executor's lookup: it answers from the snapshot, which a save on this replica refreshes before it returns and one on another replica within its notification (the poll interval at worst); the store is read only before the first snapshot.
func (*Manager) ActiveRules ¶
ActiveRules are the rules that run: not deleted, not paused. The rules engine's lookup (with Changes to follow it).
func (*Manager) BindingAPI ¶
func (m *Manager) BindingAPI() BindingAPI
BindingAPI serves m's bindings to the console.
func (*Manager) Changes ¶
Changes signals after every save, delete, pause and resume — here or on another replica (told through PostgreSQL's LISTEN/NOTIFY, and seen by the poll at the latest) — until ctx ends; one pending signal at most. Manifests change through the registry's own Changes.
func (*Manager) Current ¶
Current is the hook's current version; ok is false before the first save. A tombstone is current after a delete.
func (*Manager) CurrentAll ¶
func (m *Manager) CurrentAll(ctx context.Context) ([]BindingVersion, error)
CurrentAll is the current version of every hook ever bound, by hook.
func (*Manager) Delete ¶
func (m *Manager) Delete(ctx context.Context, hook, comment string, base Base) (BindingVersion, error)
Delete saves a tombstone: the hook becomes unbound. ErrNoBinding when it has no binding in force.
func (*Manager) DeleteRule ¶
func (m *Manager) DeleteRule(ctx context.Context, id uuid.UUID, comment string, base Base) (RuleVersion, error)
DeleteRule saves a tombstone: the rule stops. ErrDeleted when it is deleted already.
func (*Manager) HookBindings ¶
func (m *Manager) HookBindings(ctx context.Context, service string) ([]*consolev1.HookBinding, error)
HookBindings is every hook of the latest manifests (of one service, or all for "") with its binding, and every binding whose hook is no longer declared, by hook.
func (*Manager) PauseRule ¶
func (m *Manager) PauseRule(ctx context.Context, id uuid.UUID, paused bool, base Base) (RuleEntry, error)
PauseRule sets the rule's pause: paused rules start no runs.
func (*Manager) Register ¶
func (m *Manager) Register(r grpc.ServiceRegistrar)
Register registers WiringService on r. BindingService and RuleService are served by the executor and the rules engine, around BindingAPI and RuleAPI.
func (*Manager) Rollback ¶
func (m *Manager) Rollback( ctx context.Context, hook string, version int64, comment string, base Base, ) (Saved, error)
Rollback saves the definition of an older version as the next one (validated again: manifests may have changed); rolling back to a tombstone deletes.
func (*Manager) RollbackRule ¶
func (m *Manager) RollbackRule( ctx context.Context, id uuid.UUID, version int64, comment string, base Base, ) (SavedRule, error)
RollbackRule saves the name and definition of an older version as the next one; rolling back to a tombstone deletes.
func (*Manager) RuleVersion ¶
func (m *Manager) RuleVersion(ctx context.Context, id uuid.UUID, version int64) (RuleVersion, error)
RuleVersion is one version of a rule; 0: the current one.
func (*Manager) RuleVersions ¶
func (m *Manager) RuleVersions(ctx context.Context, id uuid.UUID, before int64, size int) ([]RuleVersion, error)
RuleVersions pages through a rule's versions, newest first.
func (*Manager) Save ¶
Save validates b and saves it as the next version of its hook's binding. Rejected: nothing is saved.
func (*Manager) SaveRule ¶
func (m *Manager) SaveRule( ctx context.Context, id uuid.UUID, name string, r Rule, comment string, base Base, ) (SavedRule, error)
SaveRule validates r and saves it as the next version of the rule; uuid.Nil creates a rule. Rejected: nothing is saved.
func (*Manager) ValidateRule ¶
ValidateRule checks r (and its name) against the latest manifests without saving it.
type Manifests ¶
type Manifests []*backplanev1.Manifest
Manifests is a Catalog over manifests given directly: tests, and tools that validate against manifests they hold.
func (Manifests) Activity ¶
func (ms Manifests) Activity(full string) (*backplanev1.Activity, bool)
Activity implements Catalog.
type Meta ¶
Meta are the CloudEvents attributes of the event a rule runs on, the CEL variable `meta` (time as RFC 3339).
type Option ¶
type Option func(*Manager)
Option configures New.
func Author ¶
Author names the author of a version from the request's context; default: DefaultAuthor.
func DefaultRuntime ¶ added in v0.3.0
DefaultRuntime is the runtime of definitions that name none (the installation's BACKPLANE_WIRING_RUNTIME); default: Temporal.
func PollInterval ¶
PollInterval is how often saves of other replicas are looked for (default 2s): Changes fires after them too.
type Program ¶
type Program struct {
// contains filtered or unexported fields
}
Program is a compiled binding or rule: the steps ordered into groups, options resolved, expressions compiled. It is built whole — by Compile or by json.Unmarshal of a marshaled Program — and not modified after: share it freely.
Evaluation is pure and deterministic: expressions read only the Scope, nothing reads a clock or randomness, maps are iterated in key order and results are JSON with sorted keys, so the same Program and Scope give the same bytes on every run — it is safe inside Temporal workflow code.
func CompileBinding ¶
CompileBinding checks b against the catalog and compiles it; an invalid definition is an *InvalidError.
func CompileRule ¶
CompileRule checks r against the catalog and compiles it; an invalid definition is an *InvalidError.
func (*Program) Begin ¶
Begin is the scope a body starts an item in: the item's scope with the body's steps not run yet.
func (*Program) BindItems ¶
func (p *Program) BindItems(s Scope, step string, outputs [][]byte, failed []ItemError) (Scope, error)
BindItems is s with a for-each step done: its variable the list of the items' outputs (JSON; nil: null — skipped or failed), its state the failed items.
func (*Program) Eval ¶
Eval evaluates src in the program's environment over vars (a Scope's Vars, possibly changed): the console's playground, tests. src is compiled on every call.
func (*Program) Groups ¶
Groups are the steps by level: a group's steps depend only on steps of lower groups; within a group by name. The executor does not wait for a whole group: a step starts once its Deps are done.
func (*Program) ItemOutput ¶
ItemOutput is an item's output (JSON) in the step's list: the activity's output, or the body's result on its final scope.
func (*Program) ItemScope ¶
ItemScope is s with a for-each step's item and its position bound: the scope its when, input, undo input and body see.
func (*Program) Items ¶
Items are the items a for-each step runs for on s: a list as is, a map as {key, value} by key.
func (*Program) MarshalJSON ¶
MarshalJSON is the program's serialized form: a workflow takes it as input and evaluates exactly what was compiled.
func (*Program) Masks ¶ added in v0.6.10
Masks is what the console hides of a run of the program: the secrets of its input, calls and result. Shared: read only.
func (*Program) Match ¶
Match is a rule's when on the scope of StartEvent: false — ack the event without a run. A binding, or a rule without when, matches.
func (*Program) Skip ¶
Skip is s with a step skipped by its when: its variable is {} and steps.<name>.skipped is true. Steps depending on it still run.
func (*Program) Spec ¶ added in v0.6.10
Spec is MarshalJSON's bytes without the copy: read, never written. A for-each body (KindBody) has none.
func (*Program) StartEvent ¶
StartEvent is the scope of a rule's run on an event: its payload (JSON) and attributes.
func (*Program) UndoInput ¶
UndoInput is the input (JSON) of the step's undo activity on s: its undo input, else the step's own output.
func (*Program) UnmarshalJSON ¶
UnmarshalJSON rebuilds a marshaled program. Only for a new zero Program (json.Unmarshal into one): a Program is not modified once built.
type Publisher ¶ added in v0.6.8
Publisher keeps BoundPrefix equal to the bindings in force: a pass at start, after every Changes signal and every publishResync. Replicas run it side by side; they all write what PostgreSQL holds.
type Retry ¶
type Retry struct {
// Attempts in total, the first included.
Attempts int `json:"attempts"`
InitialInterval time.Duration `json:"initial_interval"`
MaxInterval time.Duration `json:"max_interval"`
// Backoff multiplies the interval after each attempt (>= 1).
Backoff float64 `json:"backoff"`
}
Retry is a step's retry policy; zero fields are unset.
type Rule ¶
type Rule struct {
// Event is the full event name "<service>.<Event>".
Event string
// When is a CEL bool over `event` and `meta`; empty: always.
When string
Description string
// Steps are sorted by name, as Binding.Steps.
Steps []Step
// Runtime runs the rule; unspecified: the installation's default.
Runtime consolev1.Runtime
Editor *consolev1.EditorLayout
}
Rule is the definition of a rule.
func RuleFromPB ¶
func RuleFromPB(m *consolev1.RuleDefinition) Rule
RuleFromPB is the definition a message carries.
type RuleAPI ¶
type RuleAPI struct {
consolev1.UnimplementedRuleServiceServer
// contains filtered or unexported fields
}
RuleAPI is the Manager as backplane.console.v1.RuleService.
func (RuleAPI) DeleteRule ¶
func (a RuleAPI) DeleteRule( ctx context.Context, req *consolev1.DeleteRuleRequest, ) (*consolev1.DeleteRuleResponse, error)
DeleteRule implements RuleService.
func (RuleAPI) GetRule ¶
func (a RuleAPI) GetRule(ctx context.Context, req *consolev1.GetRuleRequest) (*consolev1.GetRuleResponse, error)
GetRule implements RuleService.
func (RuleAPI) ListRuleVersions ¶
func (a RuleAPI) ListRuleVersions( ctx context.Context, req *consolev1.ListRuleVersionsRequest, ) (*consolev1.ListRuleVersionsResponse, error)
ListRuleVersions implements RuleService.
func (RuleAPI) ListRules ¶
func (a RuleAPI) ListRules(ctx context.Context, req *consolev1.ListRulesRequest) (*consolev1.ListRulesResponse, error)
ListRules implements RuleService.
func (RuleAPI) PauseRule ¶
func (a RuleAPI) PauseRule(ctx context.Context, req *consolev1.PauseRuleRequest) (*consolev1.PauseRuleResponse, error)
PauseRule implements RuleService.
func (RuleAPI) ResumeRule ¶
func (a RuleAPI) ResumeRule( ctx context.Context, req *consolev1.ResumeRuleRequest, ) (*consolev1.ResumeRuleResponse, error)
ResumeRule implements RuleService.
func (RuleAPI) RollbackRule ¶
func (a RuleAPI) RollbackRule( ctx context.Context, req *consolev1.RollbackRuleRequest, ) (*consolev1.RollbackRuleResponse, error)
RollbackRule implements RuleService.
func (RuleAPI) SaveRule ¶
func (a RuleAPI) SaveRule(ctx context.Context, req *consolev1.SaveRuleRequest) (*consolev1.SaveRuleResponse, error)
SaveRule implements RuleService.
func (RuleAPI) ValidateRule ¶
func (a RuleAPI) ValidateRule( _ context.Context, req *consolev1.ValidateRuleRequest, ) (*consolev1.ValidateRuleResponse, error)
ValidateRule implements RuleService (the name is not checked: it is not part of the definition).
func (RuleAPI) WatchRules ¶
func (a RuleAPI) WatchRules( req *consolev1.WatchRulesRequest, stream grpc.ServerStreamingServer[consolev1.WatchRulesResponse], ) error
WatchRules implements RuleService: the list now, then again whenever it differs.
type RuleEntry ¶
type RuleEntry struct {
ID uuid.UUID
// Paused: no runs start.
Paused bool
CreatedAt time.Time
UpdatedAt time.Time
Current RuleVersion
}
RuleEntry is a rule with its current version.
type RuleVersion ¶
type RuleVersion struct {
RuleID uuid.UUID
Version int64
Name string
// Rule is the definition; zero on a tombstone.
Rule Rule
// Deleted marks a tombstone: the delete of the rule.
Deleted bool
Author string
Comment string
CreatedAt time.Time
RollbackOf int64 // 0: not a rollback
// ManagedBy as BindingVersion's.
ManagedBy string
}
RuleVersion is one saved version of a rule.
func (RuleVersion) PB ¶
func (v RuleVersion) PB() *consolev1.RuleVersion
PB is the version as a message.
type Saved ¶
type Saved struct {
Version BindingVersion
Violations []Violation
}
Saved is the outcome of a save: the version, or the violations the definition was rejected with.
type SavedRule ¶
type SavedRule struct {
Version RuleVersion
Violations []Violation
}
SavedRule is the outcome of a rule's save.
type Scope ¶
type Scope struct {
// contains filtered or unexported fields
}
Scope is what expressions see at one point of a run: the input, the outputs of the steps done so far and which steps were skipped. It is a value: Bind and Skip return a new Scope and leave the old one as it was.
type Step ¶
type Step struct {
// Name is an identifier unique in the definition (its key): the CEL
// variable of the step's output.
Name string
// Activity is the full activity name "<service>.<Activity>".
Activity string
// Input of the activity; zero: {}.
Input Value
// When is a CEL bool: the step runs only when true; empty: always.
When string
// After names steps this one runs after besides those its expressions
// reference.
After []string
// Undo is the compensating activity (full name) run when a later step
// fails; empty: none.
Undo string
// UndoInput is the undo activity's input; zero: the step's output.
UndoInput Value
// Retry: zero fields take the activity's defaults, then the platform's.
Retry Retry
// StartToClose bounds one attempt; 0: the activity's default, then the
// platform's.
StartToClose time.Duration
// Heartbeat: an attempt silent this long is lost; 0: the activity's
// default, else none.
Heartbeat time.Duration
Description string
// ForEach is a CEL list or map: the step runs once per item. Empty: once.
ForEach string
// As names the item variable; empty: "item". Its position is
// "<As>Index".
As string
// Concurrency bounds the items in flight; 0: DefaultConcurrency.
Concurrency int
// OnError is OnErrorFail (default, also empty) or OnErrorContinue.
OnError string
// MaxItems bounds the items; 0: DefaultMaxItems.
MaxItems int
// Steps are the body of a for-each step as a sub-flow, sorted by name;
// exclusive with Activity.
Steps []Step
// Result is each item's result when the body is Steps; zero: {}.
Result Value
}
Step is one call of an activity.
type StepAnalysis ¶
type StepAnalysis struct {
Name string
// Level is 0 for a step that depends on nothing, else one above its
// highest dependency; -1 in a cycle or with an invalid name.
Level int
// Data, After and When are the steps its input, `after` and `when`
// make it depend on; Undo the steps its undo input reads.
Data, After, When, Undo []string
// Parent is the for-each step whose body the step is in; "" at the top.
Parent string
// ItemType is the CEL type of a for-each step's item; "" without.
ItemType string
}
StepAnalysis is where a step stands in the order of execution.
type StepPlan ¶
type StepPlan struct {
Name string `json:"name"`
Activity string `json:"activity"`
// Service owns the activity: its task queue (§17).
Service string `json:"service"`
// Kind: a Temporal activity, or a workflow run as a child workflow.
Kind backplanev1.ActivityKind `json:"kind"`
// Deps are the steps this one waits for: its `after` and every step
// its input and when read.
Deps []string `json:"deps,omitempty"`
// Group is the step's level in Program.Groups: every dependency is in
// a lower group.
Group int `json:"group"`
// Conditional: the step has a when (Program.When decides).
Conditional bool `json:"conditional,omitempty"`
// Undo is the compensating activity, empty for none; UndoService and
// UndoKind as Service and Kind.
Undo string `json:"undo,omitempty"`
UndoService string `json:"undo_service,omitempty"`
UndoKind backplanev1.ActivityKind `json:"undo_kind,omitempty"`
// Retry is resolved: every field set.
Retry Retry `json:"retry"`
StartToClose time.Duration `json:"start_to_close"`
// Heartbeat 0: none.
Heartbeat time.Duration `json:"heartbeat,omitempty"`
// ForEach: the step runs once per item; nil: once.
ForEach *ForEachPlan `json:"for_each,omitempty"`
}
StepPlan is a step as the executor runs it: the activity, where it runs, what it waits for and its resolved options.
type Value ¶
type Value struct {
// contains filtered or unexported fields
}
Value is a value built by CEL: a JSON tree (google.protobuf.Value) whose strings are CEL expressions, objects are built field by field, lists item by item, and numbers, booleans and null are literals. Zero: unset, the default of its place. A Value is immutable: its tree is never changed after construction.
func ParseValue ¶
ParseValue reads a Value from its JSON form; empty or "null" text is unset.
func (Value) Expressions ¶
Expressions are the value's expressions with their JSON Pointers under base, in path order.
type ValueKind ¶
type ValueKind int
ValueKind is what a Value node is.
const ( // ValueUnset: the zero Value. ValueUnset ValueKind = iota // ValueExpr: a CEL expression (a JSON string). ValueExpr // ValueObject: an object built field by field. ValueObject // ValueList: a list built item by item. ValueList // ValueLiteral: a number, a boolean or null. ValueLiteral )
Kinds of Value nodes.
type Violation ¶
type Violation struct {
// Path is the JSON Pointer of the place in the definition
// ("/steps/send/input/to"); empty for the whole definition.
Path string
Code string
Message string
// Expr is where in the expression at Path the problem is; zero when
// it is the place itself.
Expr Range
}
Violation is one reason a definition is rejected.
func ValidateBinding ¶
ValidateBinding checks b against the catalog: every violation, empty when valid. The error is a failure to validate, not a violation.
func ValidateRule ¶
ValidateRule checks r against the catalog, as ValidateBinding.
type WiringAPI ¶
type WiringAPI struct {
consolev1.UnimplementedWiringServiceServer
// contains filtered or unexported fields
}
WiringAPI is the Manager as backplane.console.v1.WiringService: the wiring editor's catalog, analysis and refactoring. Nothing here saves.
func (WiringAPI) AnalyzeBinding ¶
func (a WiringAPI) AnalyzeBinding( _ context.Context, req *consolev1.AnalyzeBindingRequest, ) (*consolev1.AnalyzeBindingResponse, error)
AnalyzeBinding implements WiringService.
func (WiringAPI) AnalyzeRule ¶
func (a WiringAPI) AnalyzeRule( _ context.Context, req *consolev1.AnalyzeRuleRequest, ) (*consolev1.AnalyzeRuleResponse, error)
AnalyzeRule implements WiringService.
func (WiringAPI) GetWiringCatalog ¶
func (a WiringAPI) GetWiringCatalog( context.Context, *consolev1.GetWiringCatalogRequest, ) (*consolev1.GetWiringCatalogResponse, error)
GetWiringCatalog implements WiringService: every service's hooks, activities and events from its latest manifest.
func (WiringAPI) RenameStep ¶
func (a WiringAPI) RenameStep( _ context.Context, req *consolev1.RenameStepRequest, ) (*consolev1.RenameStepResponse, error)
RenameStep implements WiringService.