Stateless Flink State Snapshot#1079
Conversation
Move setLastReconciledSpec to after successful transition start
Revert "Move setLastReconciledSpec to after successful transition start"
Clear stale savepointTriggerId on B/G transition abort
Made-with: Cursor
Move setLastReconciledSpec to after successful transition start
1062465 to
21867b8
Compare
| var result = | ||
| startTransition( | ||
| context, | ||
| currentBlueGreenDeploymentType, | ||
| currentFlinkDeployment); | ||
| // Only stamp lastReconciledSpec after the transition |
|
Hello @Yanisdje |
|
@Yanisdje are you still working on this? :) |
|
Thanks @nihar4276 that would be great. I think you can for the existing work on this PR to help wrap it up and remove anything unnecessary :) |
|
Hello @gyfora and @nihar4276! Apologies for the delayed response, it seems that I was receiving the notifications in the wrong email. I could get back to it tomorrow, will keep folks updated. Thanks! |
|
Nice to meet you both 💯 . I will let Yanis take this PR to the finish line, and feel free to ping me if you need help. Thanks :) |
Problem
When a FlinkStateSnapshot CR is deleted before the FlinkStateSnapshotController has reconciled it, the cleanup() method throws a NullPointerException on getStatus().getState(). The exception is caught in a way that prevents the finalizer from being removed, causing the CR to be permanently stuck in a terminating state. This blocks namespace deletion.
Root Cause
FlinkStateSnapshotController.cleanup() and FlinkResourceContextFactory.getFlinkStateSnapshotContext() assume the status is non-null, but FlinkStateSnapshot CRs are created without a status (the status subresource is only populated when reconcile() runs). If the CR receives a deletion timestamp before reconcile() runs, JOSDK calls cleanup() directly — the only code path that initializes null status is in reconcile(), not cleanup().
The NPE propagates to JOSDK (or is caught by the controller's catch block returning noFinalizerRemoval()), causing an infinite retry loop where every attempt crashes the same way.
reconcile() already handles this case correctly:
cleanup() and updateErrorStatus() are missing this guard.
Impact
Fix
Add the same null-status initialization to cleanup() and updateErrorStatus() that already exists in reconcile(). A null-status snapshot was never triggered against Flink, so no data exists on storage and cleanup can safely proceed