@@ -58,25 +58,38 @@ class EventProcessor<R extends HasMetadata> implements EventHandler, LifecycleAw
58
58
eventSourceManager .getController ().getConfiguration ().getRetryConfiguration ()),
59
59
eventSourceManager .getController ().getConfiguration ().getConfigurationService () == null
60
60
? Metrics .NOOP
61
- : eventSourceManager .getController ().getConfiguration ().getConfigurationService ()
61
+ : eventSourceManager
62
+ .getController ()
63
+ .getConfiguration ()
64
+ .getConfigurationService ()
62
65
.getMetrics (),
63
66
eventSourceManager );
64
67
}
65
68
66
- EventProcessor (ReconciliationDispatcher <R > reconciliationDispatcher ,
69
+ EventProcessor (
70
+ ReconciliationDispatcher <R > reconciliationDispatcher ,
67
71
EventSourceManager <R > eventSourceManager ,
68
72
String relatedControllerName ,
69
73
Retry retry ) {
70
- this (eventSourceManager .getControllerResourceEventSource ().getResourceCache (), null ,
74
+ this (
75
+ eventSourceManager .getControllerResourceEventSource ().getResourceCache (),
76
+ null ,
71
77
relatedControllerName ,
72
- reconciliationDispatcher , retry , null , eventSourceManager );
78
+ reconciliationDispatcher ,
79
+ retry ,
80
+ null ,
81
+ eventSourceManager );
73
82
}
74
83
75
- private EventProcessor (Cache <R > cache , ExecutorService executor ,
84
+ private EventProcessor (
85
+ Cache <R > cache ,
86
+ ExecutorService executor ,
76
87
String relatedControllerName ,
77
- ReconciliationDispatcher <R > reconciliationDispatcher , Retry retry , Metrics metrics ,
88
+ ReconciliationDispatcher <R > reconciliationDispatcher ,
89
+ Retry retry ,
90
+ Metrics metrics ,
78
91
EventSourceManager <R > eventSourceManager ) {
79
- this .running = true ;
92
+ this .running = false ;
80
93
this .executor =
81
94
executor == null
82
95
? new ScheduledThreadPoolExecutor (
@@ -99,26 +112,31 @@ public void handleEvent(Event event) {
99
112
lock .lock ();
100
113
try {
101
114
log .debug ("Received event: {}" , event );
102
- if (!this .running ) {
103
- log .debug ("Skipping event: {} because the event handler is not started" , event );
104
- return ;
105
- }
115
+
106
116
final var resourceID = event .getRelatedCustomResourceID ();
107
117
MDCUtils .addResourceIDInfo (resourceID );
108
118
metrics .receivedEvent (event );
109
-
110
119
handleEventMarking (event );
111
- if (!eventMarker . deleteEventPresent ( resourceID ) ) {
112
- submitReconciliationExecution ( resourceID );
113
- } else {
114
- cleanupForDeletedEvent ( resourceID ) ;
120
+ if (!this . running ) {
121
+ // events are received and marked, but will be processed when started, see start() method.
122
+ log . debug ( "Skipping event: {} because the event processor is not started" , event );
123
+ return ;
115
124
}
125
+ handleMarkedEventForResource (resourceID );
116
126
} finally {
117
127
lock .unlock ();
118
128
MDCUtils .removeResourceIDInfo ();
119
129
}
120
130
}
121
131
132
+ private void handleMarkedEventForResource (ResourceID resourceID ) {
133
+ if (!eventMarker .deleteEventPresent (resourceID )) {
134
+ submitReconciliationExecution (resourceID );
135
+ } else {
136
+ cleanupForDeletedEvent (resourceID );
137
+ }
138
+ }
139
+
122
140
private void submitReconciliationExecution (ResourceID resourceID ) {
123
141
try {
124
142
boolean controllerUnderExecution = isControllerUnderExecution (resourceID );
@@ -148,8 +166,8 @@ private void submitReconciliationExecution(ResourceID resourceID) {
148
166
}
149
167
150
168
private void handleEventMarking (Event event ) {
151
- if (event instanceof ResourceEvent &&
152
- ((ResourceEvent ) event ).getAction () == ResourceAction .DELETED ) {
169
+ if (event instanceof ResourceEvent
170
+ && ((ResourceEvent ) event ).getAction () == ResourceAction .DELETED ) {
153
171
eventMarker .markDeleteEventReceived (event );
154
172
} else if (!eventMarker .deleteEventPresent (event .getRelatedCustomResourceID ())) {
155
173
eventMarker .markEventReceived (event );
@@ -177,10 +195,11 @@ void eventProcessingFinished(
177
195
// If a delete event present at this phase, it was received during reconciliation.
178
196
// So we either removed the finalizer during reconciliation or we don't use finalizers.
179
197
// Either way we don't want to retry.
180
- if (isRetryConfigured () && postExecutionControl .exceptionDuringExecution () &&
181
- !eventMarker .deleteEventPresent (resourceID )) {
182
- handleRetryOnException (executionScope ,
183
- postExecutionControl .getRuntimeException ().orElseThrow ());
198
+ if (isRetryConfigured ()
199
+ && postExecutionControl .exceptionDuringExecution ()
200
+ && !eventMarker .deleteEventPresent (resourceID )) {
201
+ handleRetryOnException (
202
+ executionScope , postExecutionControl .getRuntimeException ().orElseThrow ());
184
203
return ;
185
204
}
186
205
cleanupOnSuccessfulExecution (executionScope );
@@ -195,8 +214,7 @@ void eventProcessingFinished(
195
214
postponeReconciliationAndHandleCacheSyncEvent (resourceID );
196
215
}
197
216
} else {
198
- reScheduleExecutionIfInstructed (postExecutionControl ,
199
- executionScope .getResource ());
217
+ reScheduleExecutionIfInstructed (postExecutionControl , executionScope .getResource ());
200
218
}
201
219
}
202
220
} finally {
@@ -208,20 +226,26 @@ private void postponeReconciliationAndHandleCacheSyncEvent(ResourceID resourceID
208
226
eventSourceManager .getControllerResourceEventSource ().whitelistNextEvent (resourceID );
209
227
}
210
228
211
- private boolean isCacheReadyForInstantReconciliation (ExecutionScope < R > executionScope ,
212
- PostExecutionControl <R > postExecutionControl ) {
229
+ private boolean isCacheReadyForInstantReconciliation (
230
+ ExecutionScope < R > executionScope , PostExecutionControl <R > postExecutionControl ) {
213
231
if (!postExecutionControl .customResourceUpdatedDuringExecution ()) {
214
232
return true ;
215
233
}
216
234
String originalResourceVersion = getVersion (executionScope .getResource ());
217
- String customResourceVersionAfterExecution = getVersion (postExecutionControl
218
- .getUpdatedCustomResource ()
219
- .orElseThrow (() -> new IllegalStateException (
220
- "Updated custom resource must be present at this point of time" )));
221
- String cachedCustomResourceVersion = getVersion (cache
222
- .get (executionScope .getCustomResourceID ())
223
- .orElseThrow (() -> new IllegalStateException (
224
- "Cached custom resource must be present at this point" )));
235
+ String customResourceVersionAfterExecution =
236
+ getVersion (
237
+ postExecutionControl
238
+ .getUpdatedCustomResource ()
239
+ .orElseThrow (
240
+ () -> new IllegalStateException (
241
+ "Updated custom resource must be present at this point of time" )));
242
+ String cachedCustomResourceVersion =
243
+ getVersion (
244
+ cache
245
+ .get (executionScope .getCustomResourceID ())
246
+ .orElseThrow (
247
+ () -> new IllegalStateException (
248
+ "Cached custom resource must be present at this point" )));
225
249
226
250
if (cachedCustomResourceVersion .equals (customResourceVersionAfterExecution )) {
227
251
return true ;
@@ -233,9 +257,10 @@ private boolean isCacheReadyForInstantReconciliation(ExecutionScope<R> execution
233
257
return !cachedCustomResourceVersion .equals (originalResourceVersion );
234
258
}
235
259
236
- private void reScheduleExecutionIfInstructed (PostExecutionControl <R > postExecutionControl ,
237
- R customResource ) {
238
- postExecutionControl .getReScheduleDelay ()
260
+ private void reScheduleExecutionIfInstructed (
261
+ PostExecutionControl <R > postExecutionControl , R customResource ) {
262
+ postExecutionControl
263
+ .getReScheduleDelay ()
239
264
.ifPresent (delay -> retryEventSource ().scheduleOnce (customResource , delay ));
240
265
}
241
266
@@ -248,16 +273,15 @@ TimerEventSource<R> retryEventSource() {
248
273
* events (received meanwhile retry is in place or already in buffer) instantly or always wait
249
274
* according to the retry timing if there was an exception.
250
275
*/
251
- private void handleRetryOnException (ExecutionScope < R > executionScope ,
252
- RuntimeException exception ) {
276
+ private void handleRetryOnException (
277
+ ExecutionScope < R > executionScope , RuntimeException exception ) {
253
278
RetryExecution execution = getOrInitRetryExecution (executionScope );
254
279
var customResourceID = executionScope .getCustomResourceID ();
255
280
boolean eventPresent = eventMarker .eventPresent (customResourceID );
256
281
eventMarker .markEventReceived (customResourceID );
257
282
258
283
if (eventPresent ) {
259
- log .debug ("New events exists for for resource id: {}" ,
260
- customResourceID );
284
+ log .debug ("New events exists for for resource id: {}" , customResourceID );
261
285
submitReconciliationExecution (customResourceID );
262
286
return ;
263
287
}
@@ -277,8 +301,7 @@ private void handleRetryOnException(ExecutionScope<R> executionScope,
277
301
278
302
private void cleanupOnSuccessfulExecution (ExecutionScope <R > executionScope ) {
279
303
log .debug (
280
- "Cleanup for successful execution for resource: {}" ,
281
- getName (executionScope .getResource ()));
304
+ "Cleanup for successful execution for resource: {}" , getName (executionScope .getResource ()));
282
305
if (isRetryConfigured ()) {
283
306
retryState .remove (executionScope .getCustomResourceID ());
284
307
}
@@ -330,11 +353,18 @@ public void start() throws OperatorException {
330
353
lock .lock ();
331
354
try {
332
355
this .running = true ;
356
+ handleAlreadyMarkedEvents ();
333
357
} finally {
334
358
lock .unlock ();
335
359
}
336
360
}
337
361
362
+ private void handleAlreadyMarkedEvents () {
363
+ for (ResourceID resourceID : eventMarker .resourceIDsWithEventPresent ()) {
364
+ handleMarkedEventForResource (resourceID );
365
+ }
366
+ }
367
+
338
368
private class ControllerExecution implements Runnable {
339
369
private final ExecutionScope <R > executionScope ;
340
370
0 commit comments