-
Notifications
You must be signed in to change notification settings - Fork 23
/
provider.go
105 lines (85 loc) · 2.32 KB
/
provider.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
package otelconfig
import (
"context"
"sync"
"go.opentelemetry.io/collector/confmap"
)
// comply with confmap.Provider interface.
var _ confmap.Provider = (*Provider)(nil)
// Provider is an OTel config map provider.
//
// It allows updating the config and registering hooks.
type Provider struct {
watchFunc confmap.WatcherFunc
scheme string
hooks []func(*Config)
lock sync.Mutex // protects watchFunc & hooks
}
// NewProvider creates a new OTelConfigProvider.
func NewProvider(scheme string) *Provider {
p := &Provider{
scheme: scheme,
}
return p
}
// Retrieve implements confmap.Provider.
func (p *Provider) Retrieve(
_ context.Context,
_ string,
watchFn confmap.WatcherFunc,
) (*confmap.Retrieved, error) {
p.lock.Lock()
defer p.lock.Unlock()
p.watchFunc = watchFn
config := p.getConfig()
return confmap.NewRetrieved(config.AsMap())
}
// GetConfig returns the current config.
func (p *Provider) GetConfig() *Config {
p.lock.Lock()
defer p.lock.Unlock()
return p.getConfig()
}
func (p *Provider) getConfig() *Config {
config := New()
for _, hook := range p.hooks {
hook(config)
}
return config
}
// Shutdown implements confmap.Provider.
func (p *Provider) Shutdown(ctx context.Context) error {
p.lock.Lock()
defer p.lock.Unlock()
// Prevent UpdateConfig to run after Shutdown.
p.watchFunc = nil
return nil
}
// Scheme implements confmap.Provider.
func (p *Provider) Scheme() string { return p.scheme }
// UpdateConfig triggers Collector update asynchronously.
func (p *Provider) UpdateConfig() {
p.lock.Lock()
defer p.lock.Unlock()
p.notifyWatchFunc()
}
func (p *Provider) notifyWatchFunc() {
// Set post-hooks config and trigger update, assuming p.lock locked.
if p.watchFunc != nil {
p.watchFunc(&confmap.ChangeEvent{})
// Prevent calling watchFunc another time before the next Retrieve
// (perhaps it's even illegal). We won't miss any update though, as
// explained below.
p.watchFunc = nil
}
// If watchFunc is nil, then:
// * either we have not any Retrieve yet, so there's no reason to notify, or
// * we already notified of the change, but didn't got Retrieve yet.
}
// AddMutatingHook adds a hook to be run before applying config.
func (p *Provider) AddMutatingHook(hook func(*Config)) {
p.lock.Lock()
defer p.lock.Unlock()
p.hooks = append(p.hooks, hook)
p.notifyWatchFunc()
}