Repository navigation
Expand file tree
/
Copy pathlazy.go
More file actions
134 lines (117 loc) · 2.71 KB
/
Copy pathlazy.go
File metadata and controls
134 lines (117 loc) · 2.71 KB
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
127
128
129
130
131
132
133
134
package group
import (
"fmt"
"sync"
"time"
"github.com/docker/infrakit/pkg/spi/group"
"github.com/docker/infrakit/pkg/spi/instance"
)
// LazyConnect returns a Plugin that defers connection to actual method invocation and can optionally
// block until the connection is made.
func LazyConnect(finder func() (group.Plugin, error), retry time.Duration) group.Plugin {
p := &lazyConnect{
finder: finder,
retry: retry,
}
if retry > 0 {
p.retryCancel = make(chan struct{})
}
return p
}
// CancelWait stops the plugin from waiting / retrying to connect
func CancelWait(p group.Plugin) {
if g, is := p.(*lazyConnect); is {
if g.retryCancel != nil {
close(g.retryCancel)
}
}
}
type lazyConnect struct {
retry time.Duration
retryCancel chan struct{}
lock sync.Mutex
client group.Plugin
finder func() (group.Plugin, error)
}
func (c *lazyConnect) do(f func(p group.Plugin) error) (err error) {
c.lock.Lock()
defer c.lock.Unlock()
if c.client == nil {
c.client, err = c.finder()
if err == nil && c.client != nil {
return f(c.client)
}
if c.retry == 0 {
return err
}
tick := time.Tick(c.retry)
for {
select {
case <-tick:
case <-c.retryCancel:
return fmt.Errorf("cancelled")
}
c.client, err = c.finder()
if err == nil && c.client != nil {
break
}
}
}
return f(c.client)
}
func (c *lazyConnect) CommitGroup(grp group.Spec, pretend bool) (resp string, err error) {
err = c.do(func(p group.Plugin) error {
resp, err = p.CommitGroup(grp, pretend)
return err
})
return
}
func (c *lazyConnect) FreeGroup(id group.ID) (err error) {
err = c.do(func(p group.Plugin) error {
err = p.FreeGroup(id)
return err
})
return
}
func (c *lazyConnect) DescribeGroup(id group.ID) (desc group.Description, err error) {
err = c.do(func(p group.Plugin) error {
desc, err = p.DescribeGroup(id)
return err
})
return
}
func (c *lazyConnect) DestroyGroup(id group.ID) (err error) {
err = c.do(func(p group.Plugin) error {
err = p.DestroyGroup(id)
return err
})
return
}
func (c *lazyConnect) InspectGroups() (specs []group.Spec, err error) {
err = c.do(func(p group.Plugin) error {
specs, err = p.InspectGroups()
return err
})
return
}
func (c *lazyConnect) DestroyInstances(id group.ID, instances []instance.ID) (err error) {
err = c.do(func(p group.Plugin) error {
err = p.DestroyInstances(id, instances)
return err
})
return
}
func (c *lazyConnect) Size(id group.ID) (size int, err error) {
err = c.do(func(p group.Plugin) error {
size, err = p.Size(id)
return err
})
return
}
func (c *lazyConnect) SetSize(id group.ID, size int) (err error) {
err = c.do(func(p group.Plugin) error {
err = p.SetSize(id, size)
return err
})
return
}