-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathmain.go
124 lines (110 loc) · 3.39 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package main
import (
"context"
"os"
"os/signal"
"path/filepath"
"time"
"github.com/aperturerobotics/controllerbus/controller/loader"
"github.com/aperturerobotics/controllerbus/controller/resolver"
"github.com/aperturerobotics/controllerbus/core"
plugin_compiler "github.com/aperturerobotics/controllerbus/plugin/compiler"
plugin_shared "github.com/aperturerobotics/controllerbus/plugin/loader/shared-library/filesystem"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
const (
codegenDirPathRel = "./codegen-module/"
binaryID = "controllerbus/examples/hot-demo/codegen-demo"
binaryVersion = "0.0.1"
)
// NOTE: must have same version of:
//
// "github.com/aperturerobotics/controllerbus/hot/plugin",
var packagesList = []string{
// usual demo boilerplate controller
"github.com/aperturerobotics/controllerbus/example/boilerplate/controller",
// example of a basic demo controller package with a non-trivial relative module reference.
"./demo-controller",
// example of a cross-module reference to a package that does not contain a
// factory, but rather is a indirect dependency. "lifting" packages like
// this is necessary for hot-loading packages which reference newer versions
// of utility packages. this adds thee same plugin id prefix to the package
// and will load a copy of the package unique to the plugin.
"github.com/pkg/errors",
// example of a un-referenced package which can still be copied + configured
// properly in the output dir.
"github.com/aperturerobotics/controllerbus/cmd/controllerbus",
}
const configSetYaml = `
boilerplate-demo-0:
config:
exampleField: testing
id: controllerbus/example/boilerplate
rev: 1
loader-demo:
config:
exitAfterDur: 3s
id: controllerbus/example/hot-demo/demo-controller
rev: 1
`
func main() {
ctx := context.Background()
log := logrus.New()
log.SetLevel(logrus.DebugLevel)
le := logrus.NewEntry(log)
if err := run(ctx, le); err != nil {
os.Stderr.WriteString(err.Error())
os.Stderr.WriteString("\n")
os.Exit(1)
}
}
func run(ctx context.Context, le *logrus.Entry) error {
codegenDirPath, err := filepath.Abs(codegenDirPathRel)
if err != nil {
return err
}
// clear codegen path
if err := os.RemoveAll(codegenDirPath); err != nil && !os.IsNotExist(err) {
return err
}
le.Info("compiling example package")
if err := os.MkdirAll(codegenDirPath, 0o755); err != nil {
return err
}
outPluginsPath := "./output"
outPluginPath := filepath.Join(outPluginsPath, "demo-plugin.{buildHash}.cbus.so")
// compile the plugin with the packages listed
err = plugin_compiler.BuildPlugin(ctx, le, "./", outPluginPath, codegenDirPath, packagesList)
if err != nil {
return err
}
le.Info("loading the compiled plugin")
bus, sr, err := core.NewCoreBus(ctx, le)
if err != nil {
return err
}
sr.AddFactory(plugin_shared.NewFactory(bus))
le.Warn("If you see an error, run with -trimpath, see: https://github.com/golang/go/issues/27751")
_, _, loaderRef, err := loader.WaitExecControllerRunning(
ctx,
bus,
resolver.NewLoadControllerWithConfig(&plugin_shared.Config{
Dir: outPluginsPath,
Watch: true,
}),
nil,
)
if err != nil {
return errors.Wrap(err, "listen on api")
}
defer loaderRef.Release()
// keep running until ctrl-c or timeout
oc, ocCancel := signal.NotifyContext(ctx, os.Interrupt, os.Kill)
select {
case <-oc.Done():
case <-time.After(time.Second * 3):
}
ocCancel()
return nil
}