@@ -75,6 +75,9 @@ type controllerManager struct {
75
75
errChan chan error
76
76
stop <- chan struct {}
77
77
78
+ // stopper is the write side of the stop channel. They should have the same value.
79
+ stopper chan <- struct {}
80
+
78
81
startCache func (stop <- chan struct {}) error
79
82
}
80
83
@@ -159,9 +162,15 @@ func (cm *controllerManager) GetRESTMapper() meta.RESTMapper {
159
162
160
163
func (cm * controllerManager ) Start (stop <- chan struct {}) error {
161
164
if cm .resourceLock == nil {
162
- go cm .start (stop )
165
+ // join the passed-in stop channel as an upstream feeding into cm.stopper
166
+ go func () {
167
+ <- stop
168
+ close (cm .stopper )
169
+ }()
170
+
171
+ go cm .start ()
163
172
select {
164
- case <- stop :
173
+ case <- cm . stop :
165
174
// we are done
166
175
return nil
167
176
case err := <- cm .errChan :
@@ -178,7 +187,19 @@ func (cm *controllerManager) Start(stop <-chan struct{}) error {
178
187
RenewDeadline : 10 * time .Second ,
179
188
RetryPeriod : 2 * time .Second ,
180
189
Callbacks : leaderelection.LeaderCallbacks {
181
- OnStartedLeading : cm .start ,
190
+ // This type changes in k8s 1.12 to func(context.Context)
191
+ OnStartedLeading : func (stopleading <- chan struct {}) {
192
+ // join both stop and stopleading so they feed into cm.stopper
193
+ go func () {
194
+ select {
195
+ case <- stop :
196
+ close (cm .stopper )
197
+ case <- stopleading :
198
+ close (cm .stopper )
199
+ }
200
+ }()
201
+ cm .start ()
202
+ },
182
203
OnStoppedLeading : func () {
183
204
// Most implementations of leader election log.Fatal() here.
184
205
// Since Start is wrapped in log.Fatal when called, we can just return
@@ -194,7 +215,7 @@ func (cm *controllerManager) Start(stop <-chan struct{}) error {
194
215
go l .Run ()
195
216
196
217
select {
197
- case <- stop :
218
+ case <- cm . stop :
198
219
// We are done
199
220
return nil
200
221
case err := <- cm .errChan :
@@ -203,43 +224,33 @@ func (cm *controllerManager) Start(stop <-chan struct{}) error {
203
224
}
204
225
}
205
226
206
- func (cm * controllerManager ) start (stop <- chan struct {}) {
207
- func () {
208
- cm .mu .Lock ()
209
- defer cm .mu .Unlock ()
210
-
211
- cm .stop = stop
212
-
213
- // Start the Cache. Allow the function to start the cache to be mocked out for testing
214
- if cm .startCache == nil {
215
- cm .startCache = cm .cache .Start
216
- }
217
- go func () {
218
- if err := cm .startCache (stop ); err != nil {
219
- cm .errChan <- err
220
- }
221
- }()
227
+ func (cm * controllerManager ) start () {
228
+ cm .mu .Lock ()
229
+ defer cm .mu .Unlock ()
222
230
223
- // Wait for the caches to sync.
224
- // TODO(community): Check the return value and write a test
225
- cm .cache .WaitForCacheSync (stop )
226
-
227
- // Start the runnables after the cache has synced
228
- for _ , c := range cm .runnables {
229
- // Controllers block, but we want to return an error if any have an error starting.
230
- // Write any Start errors to a channel so we can return them
231
- ctrl := c
232
- go func () {
233
- cm .errChan <- ctrl .Start (stop )
234
- }()
231
+ // Start the Cache. Allow the function to start the cache to be mocked out for testing
232
+ if cm .startCache == nil {
233
+ cm .startCache = cm .cache .Start
234
+ }
235
+ go func () {
236
+ if err := cm .startCache (cm .stop ); err != nil {
237
+ cm .errChan <- err
235
238
}
236
-
237
- cm .started = true
238
239
}()
239
240
240
- select {
241
- case <- stop :
242
- // We are done
243
- return
241
+ // Wait for the caches to sync.
242
+ // TODO(community): Check the return value and write a test
243
+ cm .cache .WaitForCacheSync (cm .stop )
244
+
245
+ // Start the runnables after the cache has synced
246
+ for _ , c := range cm .runnables {
247
+ // Controllers block, but we want to return an error if any have an error starting.
248
+ // Write any Start errors to a channel so we can return them
249
+ ctrl := c
250
+ go func () {
251
+ cm .errChan <- ctrl .Start (cm .stop )
252
+ }()
244
253
}
254
+
255
+ cm .started = true
245
256
}
0 commit comments