Documentation ¶
Overview ¶
Package wiring provides the entry point for a Blueprint application to create and configure a wiring spec; that wiring spec can be enriched and extended by plugins; ultimately it is used by applications to generate concrete application instances.
The starting point for a Blueprint application is the NewWiringSpec function.
spec := wiring.NewWiringSpec("my_application")
Subsequently, Blueprint applications should typically not need to directly invoke methods on the WiringSpec instance; instead the applications should invoke plugins, passing the WiringSpec instance to those plugins.
After doing so,invoke the [BuildIR] function to construct the Blueprint IR for specified nodes
applicationIR, err := spec.BuildIR("my_service")
Finally, artifacts can be generated by the IR by invoking GenerateArtifacts:
err = applicationIR.GenerateArtifacts("build")
For more information, consult the Blueprint User Manual.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildApplicationIR ¶
func BuildApplicationIR(spec WiringSpec, name string, nodesToInstantiate ...string) (*ir.ApplicationNode, error)
Builds the IR of an application using the definitions of the provided spec. Returns an ir.ApplicationNode of the application.
Callers should typically provide nodesToInstantiate to specify which nodes should be instantiated in the application. This method will recursively instantiate any dependencies.
If nodesToInstantiate is empty, all nodes will be instantiated, but this might not result in an application with the desired topology. Hence the recommended approach is to explicitly specify which nodes to instantiate.
Types ¶
type BuildFunc ¶
Creates an IR node within the provided namespace or within a new child namespace. Other named IR nodes can be fetched from the provided Namespace by invoking [Namespace.Get] or other Namespace methods.
type DeferOpts ¶
type DeferOpts struct { // Defaults to false. If set to true, pushes the deferred function to the front of the queue instead of the back. Front bool }
Options for deferred functions provided with [Namespace.Defer]
type Namespace ¶
type Namespace interface { // Returns the name of this namespace Name() string // Gets an IRNode with the specified name from this namespace, placing the result in the pointer dst. // dst should typically be a pointer to an IRNode type. // If the node has already been built, it returns the existing built node. // If the node hasn't yet been built, the node's [BuildFunc] will be called and the result will be // cached and returned. // This call might recursively call [Get] on a parent namespace depending on the [nodeType] registered // for name. Get(name string, dst any) error // The same as [Get] but without creating a depending (an edge) into the current namespace. Most // plugins should use [Get] instead. Instantiate(name string, dst any) error // Gets a property from the wiring spec; dst should be a pointer to a value GetProperty(name string, key string, dst any) error // Gets a slice of properties from the wiring spec; dst should be a pointer to a slice GetProperties(name string, key string, dst any) error // Puts a node into this namespace Put(name string, node ir.IRNode) error // Creates and returns a child namespace within this namespaces. // handler will be used to determine what nodes can be built in the child namespace, and // handler's callbacks will be invoked when nodes get created within the child namespace. // // Subsequently, the namespace can be retrieved with GetNamespace // // Returns an error if the namespace has already been created DeriveNamespace(name string, handler NamespaceHandler) (Namespace, error) // Returns the child namespace with the given name. The child namespace must have been created in this // namespace, using DeriveNamespace, otherwise an error will be returned. GetNamespace(name string) (Namespace, error) // Enqueue a function to be executed after all currently-queued functions have finished executing. // Most plugins should not need to use this. // [DeferOpts] can be optionally specified. Defer(f func() error, options ...DeferOpts) // Log an info-level message Info(message string, args ...any) // Log a warn-level message Warn(message string, args ...any) // Log an error-level message Error(message string, args ...any) error }
Namespace is a dependency injection container used by Blueprint plugins during Blueprint's IR construction process. Namespaces instantiate and store IRNodes. A root Blueprint application is itself a Namespace.
A Namespace argument is passed to the BuildFunc when an IRNode is being built. An IRNode can potentially be built multiple times, in different namespaces.
If an IRNode depends on other IRNodes, those others can be fetched by calling [Namespace.Get]. If those IRNodes haven't yet been built, then their BuildFuncs will also be invoked, recursively. Conversely, if those IRNodes are already built, then the built instance is re-used.
Namespaces are hierarchical and a namespace implementation can choose to only support a subset of IRNodes. In this case, [Namespace.Get] on an unsupported IRNode will recursively get the node on the parent namespace. Namespaces inspect the nodeType argument of [WiringSpec.Define] to make this decision.
type NamespaceHandler ¶
type NamespaceHandler interface { // Reports true if this namespace can build nodes of the specified node type. // // For some node type T, if Accepts(T) returns false, then nodes of type T will // not be built in this namespace and instead the parent namespace will be called. Accepts(any) bool // After a node has been gotten from the parent namespace, AddEdge will be // called to inform the handler that the node should be passed to this namespace // as an argument. AddEdge(string, ir.IRNode) error // After a node has been built in this namespace, AddNode will be called // to enable the handler to save the built node. AddNode(string, ir.IRNode) error }
NamespaceHandler is an interface intended for use by any Blueprint plugin that wants to provide a custom namespace.
type WiringDef ¶
type WiringDef struct { Name string NodeType any Build BuildFunc Properties map[string][]any Options WiringOpts }
func (*WiringDef) AddProperty ¶
type WiringError ¶
type WiringError struct {
Errors []error
}
func (WiringError) Error ¶
func (e WiringError) Error() string
type WiringOpts ¶
type WiringOpts struct { // The type of node returned by the BuildFunc. By default this is assumed to be the same // as nodeType. Specifying this property does not currently have any effect. ReturnType any // Used by plugins to indicate whether the BuildFunc builds new nodes, or simply gets // and returns other nodes. Defaults to false. When set to true, the returned node of // a BuildFunc is not added as a node to the namespace or as an edge, since the node originated // from some other BuildFunc and therefore was already added as a node or edge. ProxyNode bool }
Additional options that can be specified when defining a WiringSpec node.
type WiringSpec ¶
type WiringSpec interface { // Provides a node definition for name. The provided [BuildFunc] build will be used to build // the node. nodeType indicates the type of node that gets built. Additional [WiringOpts] can // be optionally provided to fine-tune the node's build behavior. Define(name string, nodeType any, build BuildFunc, options ...WiringOpts) GetDef(name string) *WiringDef // For use by plugins to access the defined build functions and metadata Defs() []string // Returns names of all defined nodes Alias(name string, pointsto string) // Defines an alias to another defined node; these can be recursive GetAlias(alias string) (string, bool) // Gets the value of the specified alias, if it exists SetProperty(name string, key string, value any) // Sets a static property value in the wiring spec, replacing any existing value specified AddProperty(name string, key string, value any) // Adds a static property value in the wiring spec GetProperty(name string, key string, dst any) error // Gets a static property value from the wiring spec GetProperties(name string, key string, dst any) error // Gets all static property values from the wiring spec String() string // Returns a string representation of everything that has been defined // Errors while building a wiring spec are accumulated within the wiring spec, rather than as return values to calls AddError(err error) // Used by plugins to signify an error; the error will be returned by a call to Err or GetBlueprint Err() error // Gets an error if there is currently one BuildIR(nodesToInstantiate ...string) (*ir.ApplicationNode, error) // After defining everything, this builds the IR for the specified named nodes (implicitly including dependencies of those nodes) }
func NewWiringSpec ¶
func NewWiringSpec(name string) WiringSpec