-
Notifications
You must be signed in to change notification settings - Fork 4
/
resolver.go
103 lines (82 loc) · 2.24 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
package static
import (
"context"
"sync"
"github.com/aperturerobotics/controllerbus/config"
"github.com/aperturerobotics/controllerbus/controller"
"github.com/blang/semver"
)
// ResolverID is the resolver identifier.
const ResolverID = "static"
// 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.
type Resolver struct {
factoryMtx sync.Mutex
factories map[string]controller.Factory
}
// NewResolver constructs a new resolver.
func NewResolver(factories ...controller.Factory) *Resolver {
r := &Resolver{
factories: make(map[string]controller.Factory),
}
for _, f := range factories {
r.AddFactory(f)
}
return r
}
// GetResolverID returns the resolver identifier.
func (r *Resolver) GetResolverID() string {
return ResolverID
}
// GetResolverVersion returns the resolver version.
func (r *Resolver) GetResolverVersion() semver.Version {
return Version
}
// AddFactory adds a factory to the resolver.
func (r *Resolver) AddFactory(factory controller.Factory) {
configID := factory.GetConfigID()
version := factory.GetVersion()
r.factoryMtx.Lock()
defer r.factoryMtx.Unlock()
existing, ok := r.factories[configID]
if ok {
existingVer := existing.GetVersion()
if existingVer.GTE(version) {
return
}
}
r.factories[configID] = factory
}
// 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) {
r.factoryMtx.Lock()
defer r.factoryMtx.Unlock()
for _, f := range r.factories {
cid := f.GetConfigID()
if cid == id {
return NewConfigCtor(cid, f), nil
}
}
return nil, nil
}
// 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) {
r.factoryMtx.Lock()
defer r.factoryMtx.Unlock()
f, ok := r.factories[c.GetConfigID()]
if ok {
return f, nil
}
return nil, nil
}
// _ is a type assertion
var _ controller.FactoryResolver = ((*Resolver)(nil))