Documentation
¶
Index ¶
- Variables
- func Bind(engine Engine, deps func() memql.AuthoredRuntimeDeps, shipped ShippedNames)
- func BoundSince() time.Time
- func ConstructNameFor(f Form) string
- func GenerateRule(f Form) (string, error)
- func Validate(f Form, shipped ShippedNames) error
- type Activator
- type Engine
- type EngineShippedNames
- type Form
- type Result
- type ShippedNames
Constants ¶
This section is empty.
Variables ¶
var ErrUnbound = fmt.Errorf("routingrules: the authored runtime is not wired on this node, so a routing rule cannot be armed here. " +
"Arming happens on a node that runs the authored-construct scheduler")
ErrUnbound is what a caller gets on a node that cannot arm anything. It is its own value so a handler can tell "this node cannot" apart from "this form is wrong", which are read by different people.
Functions ¶
func Bind ¶
func Bind(engine Engine, deps func() memql.AuthoredRuntimeDeps, shipped ShippedNames)
Bind installs the activation seam. Called once from app wiring, after the authored registry and scheduler exist.
func BoundSince ¶
BoundSince reports when the seam was wired, for a status surface. The zero time means never.
func ConstructNameFor ¶
ConstructNameFor is the name the generated construct carries. It is the form's own name: a rule is addressed by name in the registry, in the decision record and on the operator's screen, and a derived name would make those three disagree.
func GenerateRule ¶
GenerateRule renders the construct. It assumes Validate passed; the one thing it re-checks is the name, because rendering an empty one produces text the parser refuses with a message about a missing identifier.
func Validate ¶
func Validate(f Form, shipped ShippedNames) error
Validate refuses a form the DSL would refuse, in the operator's vocabulary and before anything is written.
It duplicates checks the parser also makes, and that duplication is the point: the parser's message is about a construct the operator never wrote, at a line number in a file that does not exist. This one is about the field they filled in.
Types ¶
type Activator ¶
type Activator struct {
// contains filtered or unexported fields
}
Activator arms and retires routing rules.
func Bound ¶
func Bound() *Activator
Bound returns an Activator, or nil on a node where nothing was bound.
func NewActivator ¶
func NewActivator(engine Engine, deps func() memql.AuthoredRuntimeDeps, shipped ShippedNames) *Activator
NewActivator returns nil without an engine or without the authored runtime, so a caller can construct it unconditionally and a node that cannot arm anything installs nothing. A nil Activator's methods refuse with a sentence naming the missing half rather than panicking.
type Engine ¶
type Engine interface {
Execute(ctx context.Context, query string) (*memql.ExecuteResult, error)
ActivateApprovedBundle(ctx context.Context, owner, bundleId string, deps memql.AuthoredRuntimeDeps) (memql.ActivationResult, error)
RetireActiveBundle(ctx context.Context, owner, bundleId string, deps memql.AuthoredRuntimeDeps) error
}
Engine is the narrow surface arming needs. An interface rather than the concrete engine so this package is testable without a database, and so the dependency reads as three named operations instead of "everything".
type EngineShippedNames ¶
type EngineShippedNames struct{ Engine *memql.MemQLEngine }
EngineShippedNames reads the live registries.
func (EngineShippedNames) HasPolicy ¶
func (e EngineShippedNames) HasPolicy(name string) bool
func (EngineShippedNames) HasRule ¶
func (e EngineShippedNames) HasRule(name string) bool
type Form ¶
type Form struct {
// Name is the rule's construct name. It must not be a shipped name; the
// authoring pipeline's core-first resolver refuses that, and Validate
// refuses it earlier so the operator hears it from the form.
Name string
// Description becomes the /// doc comment, which is what a reader of the
// rules list sees.
Description string
// When is the condition set, keyed by the closed @when keys. A key present
// with an empty value is a condition matching only an empty value; a key
// ABSENT is no condition at all. The map preserves that distinction, which
// a struct of strings could not.
When map[string]string
// Policy is required.
Policy string
// Level optionally overrides the call's declared level.
Level string
// Precedence orders the rule. A tie with another unlocked rule refuses at
// load, so the form carries the number rather than inventing one.
Precedence int
// degrade, matching the DSL's own default.
OnUnavailable string
// Excludes removes concrete models from this rule's resolution.
Excludes []string
}
Form is what the OS sends and what the builtin takes. It is the rule as a person filled it in, and deliberately NOT the generated half -- no bundle id, no construct name, no last error. A generator that read its own past output would produce a construct whose content depended on it.
type Result ¶
type Result struct {
Name string `json:"name"`
BundleId string `json:"bundleId"`
Status string `json:"status"`
Source string `json:"source"`
Diagnostics []string `json:"diagnostics,omitempty"`
Error string `json:"error,omitempty"`
ConstructName string `json:"constructName"`
}
Result is what the builtin returns to the caller.
type ShippedNames ¶
type ShippedNames = memql.ShippedNames
ShippedNames answers "is this name the embedded tree's".
It is an ALIAS rather than a second declaration of the same two methods. Go would satisfy both structurally, so a duplicate would work and would be a second name for one contract -- and the moment either grew a method the other would not, the compiler would report it at the call site rather than where the divergence was introduced.