The kernel for your distributed system.
ControllerBus is an open-source framework for coordinating controllers with hot-reload, directive resolution, and deterministic lifecycle management.
Hot-reload
Swap controller implementations at runtime without restarting the process. Load new plugins, update configurations, and patch behavior live.
Directive-based
Controllers communicate through directives: declarative requests for capabilities. The bus resolves directives to running controllers automatically.
Deterministic lifecycle
Controllers have a well-defined lifecycle: construct, execute, release. Error handling, retry, and backoff are built into the framework.
Protobuf config
Controller configuration is defined in protobuf. Type-safe, versionable, and serializable. Configuration changes trigger controller restarts automatically.
Composable
Controllers can depend on other controllers via directives. Build complex systems from small, focused components that compose cleanly.
Cross-platform
Runs on any platform Go supports: Linux, macOS, Windows, WASM. The same controller code works in browsers and on servers.
Get started in Go
import (
"github.com/aperturerobotics/controllerbus/bus"
"github.com/aperturerobotics/controllerbus/controller"
)
// Define a controller with protobuf config.
type MyController struct {
config *Config
}
func (c *MyController) Execute(
ctx context.Context,
) error {
// Controller is running.
// Return nil to stay alive until context cancels.
// Return error to trigger restart with backoff.
<-ctx.Done()
return ctx.Err()
}
// Register and run on a bus.
b, err := bus.NewBus(ctx)
if err != nil {
return err
}
b.AddFactory(NewFactory())
// Apply configuration (triggers controller start).
err = b.ApplyConfig(ctx, myConfig)Used in Spacewave
ControllerBus is the coordination kernel at the heart of Spacewave. Every controller in the system (networking, storage, plugins, UI) is managed by the bus.
When you install a plugin, ControllerBus hot-loads it. When a device disconnects, ControllerBus tears down the associated controllers cleanly. The entire Spacewave lifecycle is bus-driven.