@@ -38,14 +38,15 @@ type Integration interface {
38
38
39
39
// ControlPlane can be used to connect to the Keptn Control Plane
40
40
type ControlPlane struct {
41
- subscriptionSource subscriptionsource.SubscriptionSource
42
- eventSource eventsource.EventSource
43
- currentSubscriptions []models.EventSubscription
44
- logger logger.Logger
45
- registered bool
46
- integrationID string
47
- logForwarder logforwarder.LogForwarder
48
- mtx * sync.RWMutex
41
+ subscriptionSource subscriptionsource.SubscriptionSource
42
+ eventSource eventsource.EventSource
43
+ currentSubscriptions []models.EventSubscription
44
+ logger logger.Logger
45
+ registered bool
46
+ integrationID string
47
+ logForwarder logforwarder.LogForwarder
48
+ mtx * sync.RWMutex
49
+ eventHandlerWaitGroup * sync.WaitGroup
49
50
}
50
51
51
52
// WithLogger sets the logger to use
@@ -61,7 +62,7 @@ func WithLogger(logger logger.Logger) func(plane *ControlPlane) {
61
62
//
62
63
// This call is blocking.
63
64
//
64
- //If you want to start the controlplane component with an own context you need to call the Regiser (ctx,integration)
65
+ //If you want to start the controlPlane component with an own context you need to call the Register (ctx,integration)
65
66
// method on your own
66
67
func RunWithGracefulShutdown (controlPlane * ControlPlane , integration Integration , shutdownTimeout time.Duration ) error {
67
68
ctxShutdown , cancel := context .WithCancel (context .Background ())
@@ -76,6 +77,7 @@ func RunWithGracefulShutdown(controlPlane *ControlPlane, integration Integration
76
77
}()
77
78
78
79
return controlPlane .Register (ctxShutdown , integration )
80
+
79
81
}
80
82
81
83
// New creates a new ControlPlane
@@ -84,13 +86,14 @@ func RunWithGracefulShutdown(controlPlane *ControlPlane, integration Integration
84
86
// and a LogForwarder to forward error logs
85
87
func New (subscriptionSource subscriptionsource.SubscriptionSource , eventSource eventsource.EventSource , logForwarder logforwarder.LogForwarder , opts ... func (plane * ControlPlane )) * ControlPlane {
86
88
cp := & ControlPlane {
87
- subscriptionSource : subscriptionSource ,
88
- eventSource : eventSource ,
89
- currentSubscriptions : []models.EventSubscription {},
90
- logger : logger .NewDefaultLogger (),
91
- logForwarder : logForwarder ,
92
- registered : false ,
93
- mtx : & sync.RWMutex {},
89
+ subscriptionSource : subscriptionSource ,
90
+ eventSource : eventSource ,
91
+ currentSubscriptions : []models.EventSubscription {},
92
+ logger : logger .NewDefaultLogger (),
93
+ logForwarder : logForwarder ,
94
+ registered : false ,
95
+ mtx : & sync.RWMutex {},
96
+ eventHandlerWaitGroup : & sync.WaitGroup {},
94
97
}
95
98
for _ , o := range opts {
96
99
o (cp )
@@ -148,30 +151,50 @@ func (cp *ControlPlane) Register(ctx context.Context, integration Integration) e
148
151
149
152
// control plane cancelled via context
150
153
case <- ctx .Done ():
151
- cp .logger .Debug ( "Controlplane cancelled via context. Unregistering..." )
154
+ cp .logger .Info ( "ControlPlane cancelled via context. Unregistering..." )
152
155
wg .Wait ()
156
+ cp .waitForEventHandlers ()
157
+ cp .cleanup ()
153
158
cp .setRegistrationStatus (false )
154
159
return nil
155
160
156
161
// control plane cancelled via error in either one of the sub components
157
162
case e := <- errC :
158
- cp .logger .Debugf ("Stopping control plane due to error: %v" , e )
159
- cp .cleanup ()
160
- cp .logger .Debug ("Waiting for components to shutdown" )
163
+ cp .logger .Errorf ("Stopping control plane due to error: %v" , e )
164
+ cp .logger .Info ("Waiting for components to shutdown" )
161
165
wg .Wait ()
166
+ cp .waitForEventHandlers ()
167
+ cp .cleanup ()
162
168
cp .setRegistrationStatus (false )
163
169
return nil
164
170
}
165
171
}
166
172
}
167
173
174
+ func (cp * ControlPlane ) waitForEventHandlers () {
175
+ cp .logger .Info ("Wait for all event handlers to finish" )
176
+ cp .eventHandlerWaitGroup .Wait ()
177
+ cp .logger .Info ("All event handlers done - ready to shut down" )
178
+ }
179
+
168
180
// IsRegistered can be called to detect whether the controlPlane is registered and ready to receive events
169
181
func (cp * ControlPlane ) IsRegistered () bool {
170
182
cp .mtx .RLock ()
171
183
defer cp .mtx .RUnlock ()
172
184
return cp .registered
173
185
}
174
186
187
+ func (cp * ControlPlane ) cleanup () {
188
+ cp .logger .Info ("Stopping subscription source..." )
189
+ if err := cp .subscriptionSource .Stop (); err != nil {
190
+ log .Fatalf ("Unable to stop subscription source: %v" , err )
191
+ }
192
+ cp .logger .Info ("Stopping event source..." )
193
+ if err := cp .eventSource .Stop (); err != nil {
194
+ log .Fatalf ("Unable to stop event source: %v" , err )
195
+ }
196
+ }
197
+
175
198
func (cp * ControlPlane ) handle (ctx context.Context , eventUpdate types.EventUpdate , integration Integration ) error {
176
199
cp .logger .Debugf ("Received an event of type: %s" , * eventUpdate .KeptnEvent .Type )
177
200
for _ , subscription := range cp .currentSubscriptions {
@@ -204,6 +227,11 @@ func (cp *ControlPlane) getSender(sender types.EventSender) types.EventSender {
204
227
}
205
228
206
229
func (cp * ControlPlane ) forwardMatchedEvent (ctx context.Context , eventUpdate types.EventUpdate , integration Integration , subscription models.EventSubscription ) error {
230
+ // increase the eventHandler WaitGroup
231
+ cp .eventHandlerWaitGroup .Add (1 )
232
+ // when the event handler is done, decrease the WaitGroup again
233
+ defer cp .eventHandlerWaitGroup .Done ()
234
+
207
235
err := eventUpdate .KeptnEvent .AddTemporaryData (
208
236
tmpDataDistributorKey ,
209
237
types.AdditionalSubscriptionData {
@@ -226,17 +254,6 @@ func (cp *ControlPlane) forwardMatchedEvent(ctx context.Context, eventUpdate typ
226
254
return nil
227
255
}
228
256
229
- func (cp * ControlPlane ) cleanup () {
230
- cp .logger .Info ("Stopping subscription source..." )
231
- if err := cp .subscriptionSource .Stop (); err != nil {
232
- log .Fatalf ("Unable to stop subscription source: %v" , err )
233
- }
234
- cp .logger .Info ("Stopping event source..." )
235
- if err := cp .eventSource .Stop (); err != nil {
236
- log .Fatalf ("Unable to stop event source: %v" , err )
237
- }
238
- }
239
-
240
257
func (cp * ControlPlane ) setRegistrationStatus (registered bool ) {
241
258
cp .mtx .Lock ()
242
259
defer cp .mtx .Unlock ()
0 commit comments