@@ -64,19 +64,22 @@ void scheduleEventFromApi(CustomResourceEvent event) {
64
64
try {
65
65
lock .lock ();
66
66
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 );
80
83
}
81
84
// In case of generation aware processing, we want to replace this even if generation not increased,
82
85
// to have the most recent copy of the event.
@@ -145,13 +148,28 @@ void eventProcessingFailed(CustomResourceEvent event) {
145
148
scheduleNotYetScheduledEventForExecution (event .resourceUid ());
146
149
} else {
147
150
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
+ }
149
157
}
150
158
} finally {
151
159
lock .unlock ();
152
160
}
153
161
}
154
162
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
+
155
173
private void scheduleNotYetScheduledEventForExecution (String uuid ) {
156
174
CustomResourceEvent notScheduledEvent = eventStore .removeEventNotScheduled (uuid );
157
175
scheduleEventForExecution (notScheduledEvent );
0 commit comments