Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/aperturerobotics/controllerbus
Modular application framework for Go.
https://github.com/aperturerobotics/controllerbus
controllers dynamic-configuration go plugin webassembly yaml
Last synced: 3 months ago
JSON representation
Modular application framework for Go.
- Host: GitHub
- URL: https://github.com/aperturerobotics/controllerbus
- Owner: aperturerobotics
- License: mit
- Created: 2018-07-11T02:00:13.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2024-05-20T21:16:08.000Z (6 months ago)
- Last Synced: 2024-05-21T07:26:05.129Z (6 months ago)
- Topics: controllers, dynamic-configuration, go, plugin, webassembly, yaml
- Language: Go
- Homepage:
- Size: 6.78 MB
- Stars: 51
- Watchers: 3
- Forks: 4
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
![Controller Bus](./doc/img/controller-bus-logo.png)
## Introduction
[![GoDoc Widget]][GoDoc] [![Go Report Card Widget]][Go Report Card]
[GoDoc]: https://godoc.org/github.com/aperturerobotics/controllerbus
[GoDoc Widget]: https://godoc.org/github.com/aperturerobotics/controllerbus?status.svg
[Go Report Card Widget]: https://goreportcard.com/badge/github.com/aperturerobotics/controllerbus
[Go Report Card]: https://goreportcard.com/report/github.com/aperturerobotics/controllerbus**ControllerBus** is a framework for **communicating control loops**:
- **Configurable**: flexible self-documenting config with Protobuf and YAML.
- **Cross-platform**: supports web browsers, servers, desktop, mobile, ...
- **Hot-loadable**: plugins and IPC dynamically add controllers at runtime.
- **Modular**: easily combine together application components w/o glue code.
- **Declarative**: de-duplicated declarative requests between controllers.The primary concepts are:
- **Config**: configuration for a controller or process.
- **Controller**: goroutine which can create & handle Directives.
- **Directive**: a cross-controller request or declaration of target state.
- **Bus**: communication channel between running Controllers.
- **Factory**: constructor for controller and configuration objects.Controller Bus provides a pattern for structuring modular Go projects.
## Examples
[![Support Server](https://img.shields.io/discord/803825858599059487.svg?label=Discord&logo=Discord&colorB=7289da&style=for-the-badge)](https://discord.gg/ZAZSt8CweP)
[![asciicast](https://asciinema.org/a/418275.svg)](https://asciinema.org/a/418275)
Basic demo of the controllerbus daemon and ConfigSet format:
```sh
cd ./cmd/controllerbus
go build -v
./controllerbus daemon
```This will load `controllerbus_daemon.yaml` and execute the boilerplate demo:
```
added directive directive="LoadControllerWithConfig"
added directive directive="ExecController `ExecControllerWithConfig`: with a directive.
- yaml/json: resolving human-readable configuration to Config objects.Config objects are Protobuf messages with attached validation functions. They
can be hand written in YAML and parsed to Protobuf or be created as Go objects.### Protobuf Configuration
The [boilerplate](./example/boilerplate/controller/config.proto) example has the
following configuration proto:```protobuf
// Config is the boilerplate configuration.
message Config {
// ExampleField is an example configuration field.
string example_field = 1;
}
```This is an example YAML configuration for this controller:
```yaml
exampleField: "Hello world!"
```With the Go API, we can use the **LoadControllerWithConfig** directive to
execute the controller with a configuration object:```go
bus.ExecOneOff(
ctx,
cb,
resolver.NewLoadControllerWithConfig(&boilerplate_controller.Config{
ExampleField: "Hello World!",
}),
nil,
)
```## Daemon and API
The [example daemon](./cmd/controllerbus) has an associated client and CLI for
the [Bus API](./bus/api), for example:```sh
$ controllerbus client exec -f controllerbus_daemon.yaml
``````json
{
"controllerInfo": {
"version": "0.0.1",
"id": "controllerbus/example/boilerplate"
},
"status": "ControllerStatus_RUNNING",
"id": "boilerplate-example-0"
}
```The bus service has the following API:
```protobuf
// ControllerBusService is a generic controller bus lookup api.
service ControllerBusService {
// GetBusInfo requests information about the controller bus.
rpc GetBusInfo(GetBusInfoRequest) returns (GetBusInfoResponse) {}
// ExecController executes a controller configuration on the bus.
rpc ExecController(controller.exec.ExecControllerRequest) returns (stream controller.exec.ExecControllerResponse) {}
}
```The RPC API is itself implemented as a controller, which can be configured:
```yaml
grpc-api:
config:
listenAddr: ":5000"
busApiConfig:
enableExecController: true
id: controllerbus/bus/api
rev: 1
```For security, the default value of `enableExecController` is `false` to disallow
executing controllers via the API.The structure under `cmd/controllerbus` and `example/boilerplate` are examples
which are intended to be copied to other projects, which reference the core
`controllerbus` controllers. A minimal program is as follows:```go
ctx := context.Background()
log := logrus.New()
log.SetLevel(logrus.DebugLevel)
le := logrus.NewEntry(log)b, sr, err := core.NewCoreBus(ctx, le)
if err != nil {
t.Fatal(err.Error())
}
sr.AddFactory(NewFactory(b))execDir := resolver.NewLoadControllerWithConfig(&Config{
ExampleField: "testing",
})
_, ctrlRef, err := bus.ExecOneOff(ctx, b, execDir, nil)
if err != nil {
t.Fatal(err.Error())
}
defer ctrlRef.Release()
```This provides logging, context cancelation. A single Factory is attached which
provides support for the Config type, (see the boilerplate example).## Daemon and Client CLIs
Plugins can be bundled together with a set of root configurations into a CLI.
This can be used to bundle modules into a daemon and/or client for an
application - similar to the [controllerbus cli](./cmd/controllerbus).## Testing
An in-memory Bus can be created for testing, an
[example](./example/boilerplate/controller/controller_test.go) is provided in
the boilerplate package.## Plugins
[![asciicast](https://asciinema.org/a/I4LOCViLwzRlztYc1rytgAxWp.svg)](./example/plugin-demo)
**⚠ Plugins are experimental and not yet feature-complete.**
The [plugin](./plugin) system and compiler scans a set of Go packages for
ControllerBus factories and bundles them together into a hashed Plugin bundle.
The compiler CLI can watch code files for changes and re-build automatically.
Multiple plugin loaders and binary formats are supported.```
USAGE:
controllerbus hot compile - compile packages specified as arguments onceOPTIONS:
--build-prefix value prefix to prepend to import paths, generated on default [$CONTROLLER_BUS_PLUGIN_BUILD_PREFIX]
--codegen-dir value path to directory to create/use for codegen, if empty uses tmpdir [$CONTROLLER_BUS_CODEGEN_DIR]
--output PATH, -o PATH write the output plugin to PATH - accepts {buildHash} [$CONTROLLER_BUS_OUTPUT]
--plugin-binary-id value binary id for the output plugin [$CONTROLLER_BUS_PLUGIN_BINARY_ID]
--plugin-binary-version value binary version for the output plugin, accepts {buildHash} [$CONTROLLER_BUS_PLUGIN_BINARY_VERSION]
--no-cleanup disable cleaning up the codegen dirs [$CONTROLLER_BUS_NO_CLEANUP]
--help, -h show help
```The CLI will analyze a list of Go package paths, discover all Factories
available in the packages, generate a Go module for importing all of the
factories into a single Plugin, and compile that package to a .so library.## Projects
List of projects known to use Controller Bus:
- [Bifrost]: networking and p2p library + daemon
[Bifrost]: https://github.com/aperturerobotics/bifrost
Open a PR to add your project to this list!
## Support
Please open a [GitHub issue] with any questions / issues.
[GitHub issue]: https://github.com/aperturerobotics/controllerbus/issues/new
... or feel free to reach out on [Matrix Chat] or [Discord].
[Discord]: https://discord.gg/ZAZSt8CweP
[Matrix Chat]: https://matrix.to/#/#aperturerobotics:matrix.org## License
MIT