blob: b84e77051efbc932ba87102ebd829b0a4cd5c86b (
plain)
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
|
package discovery
import (
"context"
"sync"
"github.com/eduvpn/eduvpn-common/internal/log"
)
type Manager struct {
disco *Discovery
cancel context.CancelFunc
mu sync.RWMutex
wait sync.WaitGroup
}
func NewManager(disco *Discovery) *Manager {
return &Manager{disco: disco}
}
func (m *Manager) lock(write bool) {
log.Logger.Debugf("Locking write: %v", write)
if write {
m.mu.Lock()
return
}
m.mu.RLock()
}
func (m *Manager) unlock(write bool) {
log.Logger.Debugf("Unlocking write: %v", write)
if write {
m.mu.Unlock()
return
}
m.mu.RUnlock()
}
func (m *Manager) Discovery(write bool) (*Discovery, func()) {
log.Logger.Debugf("Requesting discovery write: %v", write)
if write {
m.wait.Wait()
}
m.lock(write)
return m.disco, func() {
m.unlock(write)
}
}
func (m *Manager) Cancel() {
if m.cancel != nil {
m.cancel()
}
m.wait.Wait()
}
func (m *Manager) Startup(ctx context.Context, cb func()) {
ctx, cancel := context.WithCancel(ctx)
m.cancel = cancel
m.wait.Add(1)
go func() {
m.lock(false)
discoCopy, err := m.disco.Copy()
if err != nil {
log.Logger.Warningf("internal error, failed to clone discovery, %v", err)
return
}
m.unlock(false)
// we already log the warning
discoCopy.Servers(ctx) //nolint:errcheck
m.lock(true)
m.disco.UpdateServers(discoCopy)
m.unlock(true)
m.wait.Done()
select {
case <-ctx.Done():
return
default:
if cb == nil {
return
}
cb()
}
}()
}
|