@@ -58,25 +58,38 @@ class EventProcessor<R extends HasMetadata> implements EventHandler, LifecycleAw
5858 eventSourceManager .getController ().getConfiguration ().getRetryConfiguration ()),
5959 eventSourceManager .getController ().getConfiguration ().getConfigurationService () == null
6060 ? Metrics .NOOP
61- : eventSourceManager .getController ().getConfiguration ().getConfigurationService ()
61+ : eventSourceManager
62+ .getController ()
63+ .getConfiguration ()
64+ .getConfigurationService ()
6265 .getMetrics (),
6366 eventSourceManager );
6467 }
6568
66- EventProcessor (ReconciliationDispatcher <R > reconciliationDispatcher ,
69+ EventProcessor (
70+ ReconciliationDispatcher <R > reconciliationDispatcher ,
6771 EventSourceManager <R > eventSourceManager ,
6872 String relatedControllerName ,
6973 Retry retry ) {
70- this (eventSourceManager .getControllerResourceEventSource ().getResourceCache (), null ,
74+ this (
75+ eventSourceManager .getControllerResourceEventSource ().getResourceCache (),
76+ null ,
7177 relatedControllerName ,
72- reconciliationDispatcher , retry , null , eventSourceManager );
78+ reconciliationDispatcher ,
79+ retry ,
80+ null ,
81+ eventSourceManager );
7382 }
7483
75- private EventProcessor (Cache <R > cache , ExecutorService executor ,
84+ private EventProcessor (
85+ Cache <R > cache ,
86+ ExecutorService executor ,
7687 String relatedControllerName ,
77- ReconciliationDispatcher <R > reconciliationDispatcher , Retry retry , Metrics metrics ,
88+ ReconciliationDispatcher <R > reconciliationDispatcher ,
89+ Retry retry ,
90+ Metrics metrics ,
7891 EventSourceManager <R > eventSourceManager ) {
79- this .running = true ;
92+ this .running = false ;
8093 this .executor =
8194 executor == null
8295 ? new ScheduledThreadPoolExecutor (
@@ -99,26 +112,31 @@ public void handleEvent(Event event) {
99112 lock .lock ();
100113 try {
101114 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+
106116 final var resourceID = event .getRelatedCustomResourceID ();
107117 MDCUtils .addResourceIDInfo (resourceID );
108118 metrics .receivedEvent (event );
109-
110119 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 ;
115124 }
125+ handleMarkedEventForResource (resourceID );
116126 } finally {
117127 lock .unlock ();
118128 MDCUtils .removeResourceIDInfo ();
119129 }
120130 }
121131
132+ private void handleMarkedEventForResource (ResourceID resourceID ) {
133+ if (!eventMarker .deleteEventPresent (resourceID )) {
134+ submitReconciliationExecution (resourceID );
135+ } else {
136+ cleanupForDeletedEvent (resourceID );
137+ }
138+ }
139+
122140 private void submitReconciliationExecution (ResourceID resourceID ) {
123141 try {
124142 boolean controllerUnderExecution = isControllerUnderExecution (resourceID );
@@ -148,8 +166,8 @@ private void submitReconciliationExecution(ResourceID resourceID) {
148166 }
149167
150168 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 ) {
153171 eventMarker .markDeleteEventReceived (event );
154172 } else if (!eventMarker .deleteEventPresent (event .getRelatedCustomResourceID ())) {
155173 eventMarker .markEventReceived (event );
@@ -177,10 +195,11 @@ void eventProcessingFinished(
177195 // If a delete event present at this phase, it was received during reconciliation.
178196 // So we either removed the finalizer during reconciliation or we don't use finalizers.
179197 // 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 ());
184203 return ;
185204 }
186205 cleanupOnSuccessfulExecution (executionScope );
@@ -195,8 +214,7 @@ void eventProcessingFinished(
195214 postponeReconciliationAndHandleCacheSyncEvent (resourceID );
196215 }
197216 } else {
198- reScheduleExecutionIfInstructed (postExecutionControl ,
199- executionScope .getResource ());
217+ reScheduleExecutionIfInstructed (postExecutionControl , executionScope .getResource ());
200218 }
201219 }
202220 } finally {
@@ -208,20 +226,26 @@ private void postponeReconciliationAndHandleCacheSyncEvent(ResourceID resourceID
208226 eventSourceManager .getControllerResourceEventSource ().whitelistNextEvent (resourceID );
209227 }
210228
211- private boolean isCacheReadyForInstantReconciliation (ExecutionScope < R > executionScope ,
212- PostExecutionControl <R > postExecutionControl ) {
229+ private boolean isCacheReadyForInstantReconciliation (
230+ ExecutionScope < R > executionScope , PostExecutionControl <R > postExecutionControl ) {
213231 if (!postExecutionControl .customResourceUpdatedDuringExecution ()) {
214232 return true ;
215233 }
216234 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" )));
225249
226250 if (cachedCustomResourceVersion .equals (customResourceVersionAfterExecution )) {
227251 return true ;
@@ -233,9 +257,10 @@ private boolean isCacheReadyForInstantReconciliation(ExecutionScope<R> execution
233257 return !cachedCustomResourceVersion .equals (originalResourceVersion );
234258 }
235259
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 ()
239264 .ifPresent (delay -> retryEventSource ().scheduleOnce (customResource , delay ));
240265 }
241266
@@ -248,16 +273,15 @@ TimerEventSource<R> retryEventSource() {
248273 * events (received meanwhile retry is in place or already in buffer) instantly or always wait
249274 * according to the retry timing if there was an exception.
250275 */
251- private void handleRetryOnException (ExecutionScope < R > executionScope ,
252- RuntimeException exception ) {
276+ private void handleRetryOnException (
277+ ExecutionScope < R > executionScope , RuntimeException exception ) {
253278 RetryExecution execution = getOrInitRetryExecution (executionScope );
254279 var customResourceID = executionScope .getCustomResourceID ();
255280 boolean eventPresent = eventMarker .eventPresent (customResourceID );
256281 eventMarker .markEventReceived (customResourceID );
257282
258283 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 );
261285 submitReconciliationExecution (customResourceID );
262286 return ;
263287 }
@@ -277,8 +301,7 @@ private void handleRetryOnException(ExecutionScope<R> executionScope,
277301
278302 private void cleanupOnSuccessfulExecution (ExecutionScope <R > executionScope ) {
279303 log .debug (
280- "Cleanup for successful execution for resource: {}" ,
281- getName (executionScope .getResource ()));
304+ "Cleanup for successful execution for resource: {}" , getName (executionScope .getResource ()));
282305 if (isRetryConfigured ()) {
283306 retryState .remove (executionScope .getCustomResourceID ());
284307 }
@@ -330,11 +353,18 @@ public void start() throws OperatorException {
330353 lock .lock ();
331354 try {
332355 this .running = true ;
356+ handleAlreadyMarkedEvents ();
333357 } finally {
334358 lock .unlock ();
335359 }
336360 }
337361
362+ private void handleAlreadyMarkedEvents () {
363+ for (ResourceID resourceID : eventMarker .resourceIDsWithEventPresent ()) {
364+ handleMarkedEventForResource (resourceID );
365+ }
366+ }
367+
338368 private class ControllerExecution implements Runnable {
339369 private final ExecutionScope <R > executionScope ;
340370
0 commit comments