Documentation
¶
Overview ¶
Package graphkit is the runtime under a project's generated composition graph (internal/app/graph_gen.go): memoized construction of each node, the root's Build — force the closure, then seal — and the lifecycle nodes of what was built, in the order it was built, for lifecyclekit.Supervise.
The graph itself is generated Go. Every edge is a value expression in the project's internal/app/compose.go, and every accessor is a typed method on the project's *app.Graph that calls Get. Nothing here resolves a dependency, looks a value up by name, or inspects a type: which node a Deps field gets was decided at generate time, and which lifecycle methods a node has was read off its type by the generator and handed to Get as a Node literal.
func (g *Graph) Billing() *billing.Service {
return graphkit.Get(&g.b, &g.m.Billing, "billing", g.newBilling, nil)
}
Construction is eager within a root and fails loud at boot: Build forces the root's whole closure before anything runs, a construction error unwinds with the path that reached it ("build server: api_listener → user_routes → billing: …"), and once the graph is sealed an accessor for a node the root never reached panics instead of constructing it on a first request.
A Builder is used from one goroutine while it builds. After Build, reading an already-built node is safe from any goroutine.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrSealed = errors.New("graphkit: the graph is sealed")
ErrSealed is the cause of the panic an accessor raises for a node the root's Build did not construct.
Functions ¶
func Catch ¶
func Catch(f func()) (err error)
Catch runs f and returns the construction error a node's accessor panicked with, for a caller that uses the graph's accessors outside Build. Any other panic is re-raised.
func Get ¶
func Get[T any](b *Builder, m *Memo[T], name string, ctor func() (T, error), node func(T) lifecyclekit.Node) T
Get returns the node m memoizes, constructing it with ctor the first time. name labels it in errors and in the supervisor's logs. node, when non-nil, is the node's lifecycle — its Run, Drain, Close and Ready methods, read off its type at generate time; a Node with none of them is not supervised.
A construction error does not return: it panics, carrying the path of nodes that reached it, and Build recovers it. Calling an accessor outside Build (a hand-written main using the graph unsealed) gets the same panic; Catch turns it into an error.
Types ¶
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
Builder is one graph's construction state. The zero value is ready to use.
func (*Builder) Build ¶
Build constructs a root: force calls the root's field accessors, so every node the root reaches is constructed once, dependencies first. Build then seals the graph. A construction error comes back as "build <root>: a → b → c: <cause>". Building a second root on a sealed graph is an error: one process runs one root.
func (*Builder) Built ¶
Built is the name of every constructed node, in construction-completion order: each after everything it depends on.
func (*Builder) Nodes ¶
func (b *Builder) Nodes() []lifecyclekit.Node
Nodes are the lifecycle nodes of every constructed node that has a Run, Drain, Close or Ready, in construction order — the order Supervise starts them in, so a node starts after everything it depends on and stops before.
func (*Builder) Supervise ¶
func (b *Builder) Supervise(ctx context.Context, policy lifecyclekit.Policy, probes *serverkit.Probes) error
Supervise runs the built nodes under lifecyclekit.Supervise until ctx ends. Every node that reports Ready joins probes' /readyz, and probes' Drainer is the policy's readiness gate and shutdown budget when the policy names none. probes may be nil — a root with no probe route. Call it after Build.