7
7
"strconv"
8
8
"sync"
9
9
"syscall"
10
+ "time"
10
11
11
12
log "github.com/Sirupsen/logrus"
12
13
"github.com/docker/infrakit/pkg/discovery"
@@ -104,13 +105,34 @@ func pluginCommand(plugins func() discovery.Plugins) *cobra.Command {
104
105
input = append (input , ch )
105
106
}
106
107
107
- var wait sync.WaitGroup
108
+ // This is the channel to send signal that plugins are stopped out of band so stop waiting.
109
+ noRunningPlugins := make (chan struct {})
110
+ // This is the channel for completion of waiting.
111
+ waitDone := make (chan struct {})
112
+ // This is the channel to stop scanning for running plugins.
113
+ pluginScanDone := make (chan struct {})
108
114
115
+ var wait sync.WaitGroup
109
116
if * doWait {
110
117
wait .Add (1 )
118
+ go func () {
119
+ wait .Wait () // wait for everyone to complete
120
+ close (waitDone )
121
+ }()
122
+ }
123
+
124
+ // Now start all the plugins
125
+ started := []string {}
126
+
127
+ // We do a count of the plugins running before we start.
128
+ var before , after = 0 , 0
129
+
130
+ if m , err := plugins ().List (); err != nil {
131
+ log .Warningln ("Problem listing current plugins:" , err , "continue." )
132
+ } else {
133
+ before = len (m )
111
134
}
112
135
113
- // now start all the plugins
114
136
for _ , pluginToStart := range args {
115
137
fmt .Println ("Starting up" , pluginToStart )
116
138
@@ -123,6 +145,8 @@ func pluginCommand(plugins func() discovery.Plugins) *cobra.Command {
123
145
Plugin : plugin .Name (name ),
124
146
Started : func (config * types.Any ) {
125
147
fmt .Println (name , "started." )
148
+
149
+ started = append (started , name )
126
150
wait .Done ()
127
151
},
128
152
Error : func (config * types.Any , err error ) {
@@ -133,11 +157,55 @@ func pluginCommand(plugins func() discovery.Plugins) *cobra.Command {
133
157
}
134
158
}
135
159
136
- wait .Wait () // wait for everyone to complete
160
+ if m , err := plugins ().List (); err == nil {
161
+ after = len (m )
162
+ }
163
+
164
+ // Here we scan the plugins. If we are starting up the plugins, wait a little bit
165
+ // for them to show up. Then we start scanning to see if the sockets are gone.
166
+ // If the sockets are gone, then we can safely exit.
167
+ if * doWait {
168
+ go func () {
169
+ interval := 5 * time .Second
170
+
171
+ now := after
172
+ if now <= before {
173
+ // Here we have fewer plugins running then before. Wait a bit
174
+ time .Sleep (interval )
175
+ }
176
+ checkNow := time .Tick (interval )
177
+ for {
178
+ select {
179
+ case <- pluginScanDone :
180
+ log .Infoln ("--wait mode: stop scanning." )
181
+ return
182
+
183
+ case <- checkNow :
184
+ if m , err := plugins ().List (); err == nil {
185
+ now = len (m )
186
+ }
187
+ if now == 0 {
188
+ log .Infoln ("--wait mode: scan found no plugins." )
189
+ close (noRunningPlugins )
190
+ }
191
+ }
192
+ }
193
+ }()
194
+ }
195
+
196
+ // Here we wait for either wait group to be done or if they are killed out of band.
197
+ select {
198
+ case <- waitDone :
199
+ log .Infoln ("All plugins completed. Exiting." )
200
+ case <- noRunningPlugins :
201
+ log .Infoln ("Plugins aren't running anymore. Exiting." )
202
+ }
137
203
138
204
for _ , monitor := range monitors {
139
205
monitor .Stop ()
140
206
}
207
+
208
+ close (pluginScanDone )
141
209
return nil
142
210
}
143
211
0 commit comments