@@ -64,19 +64,22 @@ void scheduleEventFromApi(CustomResourceEvent event) {
6464 try {
6565 lock .lock ();
6666 log .debug ("Scheduling event from Api: {}" , event );
67- if (event .getAction () == Action .DELETED ) {
68- // This removes data from memory for deleted resource (prevent memory leak basically).
69- // Its quite interesting that this is always sufficient here (no finalizer or other mechanism needs to be involved).
70- // Thus, if operator is running we get DELETE the event, if not the memory is already gone anyways.
71- eventStore .removeLastGenerationForDeletedResource (event .resourceUid ());
72- if (event .getResource ().getMetadata ().getDeletionTimestamp () != null ) {
73- // Note that we always use finalizers, we want to process delete event just in corner case,
74- // when we are not able to add finalizer (lets say because of optimistic locking error, and the resource was deleted instantly).
75- // We want to skip in case of finalizer was there since we don't want to execute delete method always at least 2x,
76- // which would be the result if we don't skip here. (there is no deletion timestamp if resource deleted without finalizer.)
77- log .debug ("Skipping delete event since deletion timestamp is present on resource, so finalizer was in place." );
78- return ;
79- }
67+ if (event .getAction () == Action .DELETED && event .getResource ().getMetadata ().getDeletionTimestamp () != null ) {
68+ // This removes data from memory for deleted resource (prevent memory leak).
69+ // There is am extreme corner case when there is no finalizer, we ignore this situation now.
70+ eventStore .cleanup (event .resourceUid ());
71+ // Note that we always use finalizers, we want to process delete event just in corner case,
72+ // when we are not able to add finalizer (lets say because of optimistic locking error, and the resource was deleted instantly).
73+ // We want to skip in case of finalizer was there since we don't want to execute delete method always at least 2x,
74+ // which would be the result if we don't skip here. (there is no deletion timestamp if resource deleted without finalizer.)
75+ log .debug ("Skipping delete event since deletion timestamp is present on resource, so finalizer was in place." );
76+ return ;
77+ }
78+ if (generationAware ) {
79+ // we have to store the last event for generation aware retries, since if we received new events since
80+ // the execution, which did not have increased generation we will fail automatically on a conflict
81+ // on a retry.
82+ eventStore .addLastEventForGenerationAwareRetry (event );
8083 }
8184 // In case of generation aware processing, we want to replace this even if generation not increased,
8285 // to have the most recent copy of the event.
@@ -145,13 +148,28 @@ void eventProcessingFailed(CustomResourceEvent event) {
145148 scheduleNotYetScheduledEventForExecution (event .resourceUid ());
146149 } else {
147150 log .debug ("Event processing failed. Attempting to re-schedule the event: {}" , event );
148- scheduleEventForExecution (event );
151+ if (generationAware ) {
152+ CustomResourceEvent eventToRetry = selectEventToRetry (event );
153+ scheduleEventForExecution (eventToRetry );
154+ } else {
155+ scheduleEventForExecution (event );
156+ }
149157 }
150158 } finally {
151159 lock .unlock ();
152160 }
153161 }
154162
163+ private CustomResourceEvent selectEventToRetry (CustomResourceEvent event ) {
164+ CustomResourceEvent lastEvent = eventStore .getReceivedLastEventForGenerationAwareRetry (event .resourceUid ());
165+ if (!event .getResource ().getMetadata ().getResourceVersion ()
166+ .equals (lastEvent .getResource ().getMetadata ().getResourceVersion ())) {
167+ return lastEvent ;
168+ } else {
169+ return event ;
170+ }
171+ }
172+
155173 private void scheduleNotYetScheduledEventForExecution (String uuid ) {
156174 CustomResourceEvent notScheduledEvent = eventStore .removeEventNotScheduled (uuid );
157175 scheduleEventForExecution (notScheduledEvent );
0 commit comments