-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathresolver.go
109 lines (96 loc) · 2.75 KB
/
resolver.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
package plugin
import (
"context"
"strings"
"sync"
"github.com/aperturerobotics/controllerbus/bus"
"github.com/aperturerobotics/controllerbus/config"
"github.com/aperturerobotics/controllerbus/controller"
"github.com/aperturerobotics/controllerbus/controller/resolver/static"
"github.com/blang/semver/v4"
)
// Version is the resolver version.
var Version = semver.MustParse("0.0.1")
// Resolver implements the controller resolver using a list of built-in
// controller implementations.
//
// Does not require semantic versioning for binary versions.
type Resolver struct {
ctx context.Context
id string
pluginBinaryID string
pluginBinaryVersion string
staticResolver *static.Resolver
bus bus.Bus
mtx sync.Mutex
preUnload []func()
}
// NewResolver constructs a new resolver with a plugin binary.
func NewResolver(
ctx context.Context,
bus bus.Bus,
pluginBinaryID string,
pluginBinaryVersion string,
factories ...controller.Factory,
) *Resolver {
id := strings.Join([]string{
"controllerbus",
"hot",
"plugin",
pluginBinaryID,
pluginBinaryVersion,
"static-resolver",
}, "/")
staticResolver := static.NewResolver(factories...)
return &Resolver{
ctx: ctx,
bus: bus,
id: id,
staticResolver: staticResolver,
pluginBinaryID: pluginBinaryID,
pluginBinaryVersion: pluginBinaryVersion,
}
}
// GetResolverID returns the resolver identifier.
func (r *Resolver) GetResolverID() string {
return r.id
}
// GetResolverVersion returns the resolver version.
func (r *Resolver) GetResolverVersion() semver.Version {
return Version
}
// GetConfigCtorByID returns a config constructor matching the ID.
// If none found, return nil, nil
func (r *Resolver) GetConfigCtorByID(
ctx context.Context, id string,
) (config.Constructor, error) {
return r.staticResolver.GetConfigCtorByID(ctx, id)
}
// GetFactoryMatchingConfig returns the factory that matches the config.
// If no factory is found, return nil.
// If an unexpected error occurs, return it.
func (r *Resolver) GetFactoryMatchingConfig(
ctx context.Context, c config.Config,
) (controller.Factory, error) {
tfac, err := r.staticResolver.GetFactoryMatchingConfig(ctx, c)
if err != nil || tfac == nil {
return tfac, err
}
// wrap factories with pre-unload hook
sf := NewStaticPluginFactory(r.ctx, tfac, r.pluginBinaryID, r.bus)
r.mtx.Lock()
r.preUnload = append(r.preUnload, sf.Close)
r.mtx.Unlock()
return sf, nil
}
// PrePluginUnload is called just before the plugin is unloaded.
func (r *Resolver) PrePluginUnload() {
r.mtx.Lock()
for _, f := range r.preUnload {
f()
}
r.preUnload = nil
r.mtx.Unlock()
}
// _ is a type assertion
var _ PluginResolver = ((*Resolver)(nil))