forked from docker-archive/deploykit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstate.go
126 lines (98 loc) · 2.27 KB
/
state.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
125
126
package group
import (
"fmt"
"github.com/docker/infrakit/pkg/plugin/group/types"
"github.com/docker/infrakit/pkg/plugin/group/util"
"github.com/docker/infrakit/pkg/spi/flavor"
"github.com/docker/infrakit/pkg/spi/group"
"github.com/docker/infrakit/pkg/spi/instance"
"sync"
)
// Supervisor watches over a group of instances.
type Supervisor interface {
util.RunStop
ID() group.ID
Size() uint
PlanUpdate(scaled Scaled, settings groupSettings, newSettings groupSettings) (updatePlan, error)
}
type groupSettings struct {
self *instance.LogicalID
instancePlugin instance.Plugin
flavorPlugin flavor.Plugin
config types.Spec
}
type groupContext struct {
settings groupSettings
supervisor Supervisor
scaled *scaledGroup
update updatePlan
lock sync.RWMutex
}
func (c *groupContext) setUpdate(plan updatePlan) {
c.lock.Lock()
defer c.lock.Unlock()
c.update = plan
}
func (c *groupContext) updating() bool {
c.lock.RLock()
defer c.lock.RUnlock()
return c.update != nil
}
func (c *groupContext) stopUpdating() {
c.lock.Lock()
defer c.lock.Unlock()
if c.update != nil {
c.update.Stop()
c.update = nil
}
}
func (c *groupContext) changeSettings(settings groupSettings) {
c.lock.Lock()
defer c.lock.Unlock()
c.settings = settings
c.scaled.changeSettings(settings)
}
type groups struct {
byID map[group.ID]*groupContext
lock sync.RWMutex
}
func (g *groups) del(id group.ID) {
g.lock.Lock()
defer g.lock.Unlock()
delete(g.byID, id)
}
func (g *groups) get(id group.ID) (*groupContext, bool) {
g.lock.RLock()
defer g.lock.RUnlock()
logical, exists := g.byID[id]
return logical, exists
}
func (g *groups) put(id group.ID, context *groupContext) {
g.lock.Lock()
defer g.lock.Unlock()
_, exists := g.byID[id]
if exists {
panic(fmt.Sprintf("Attempt to overwrite group %v", id))
}
g.byID[id] = context
}
func (g *groups) forEach(fn func(group.ID, *groupContext) error) error {
g.lock.RLock()
defer g.lock.RUnlock()
for id, ctx := range g.byID {
if err := fn(id, ctx); err != nil {
return err
}
}
return nil
}
type sortByID []instance.Description
func (n sortByID) Len() int {
return len(n)
}
func (n sortByID) Swap(i, j int) {
n[i], n[j] = n[j], n[i]
}
func (n sortByID) Less(i, j int) bool {
return n[i].ID < n[j].ID
}