fix(executor): fail immediately on deterministic plugin errors - #7823
Conversation
Plugin errors carrying BadTaskSpecification or MetadataTooLarge now skip the system-failure retry loop and fail the TaskAction immediately, since retrying cannot change a deterministic outcome. Follow-up to flyteorg#7799. Signed-off-by: davidlin20dev <davidlin20.dev@gmail.com>
|
Hi @pingsutw, when I was implementing this I left Tracing it in flyte/executor/pkg/plugin/k8s/plugin_manager.go Lines 221 to 227 in d2c1795 The state reader returns version flyte/executor/pkg/plugin/state_manager.go Lines 43 to 52 in d2c1795 Since That also means adding What the reachable branch does: it's a flyte/executor/pkg/controller/taskaction_controller.go Lines 468 to 473 in d2c1795 So when the task has retries configured, corrupt state actually recovers, the next attempt starts fresh. But with default retries (0), That's why I think the real fix here is Let me know if this makes sense, not sure if I'm missing something here. |
|
Thanks for tracing the code. we can change pluginsCore.PhaseInfoRetryableFailure to PhaseInfoFailureWithCleanup, so the task won't retry on this error |
|
thanks for the review! I'll make the change in this PR. One small question about |
Per review, corrupted plugin state is deterministic, so Handle now returns a permanent system failure with cleanup instead of a retryable one. Uses the SYSTEM-kind variant pending the attribution question in the PR thread. Signed-off-by: davidlin20dev <davidlin20.dev@gmail.com>
|
Just pushed the change. I went with PhaseInfoSystemFailureWithCleanup from my question above, it's a one-word swap back if needed. Let me know if you'd rather keep USER. Thanks! |
|
LGTM, thanks |
What changes were proposed in this pull request?
Plugin errors carrying a deterministic error code now fail the TaskAction immediately instead of consuming system-failure attempts.
recordSystemErrorchecks the error's code before touchingStatus.SystemFailures, and routes a match straight tofinalizePermanentFailurewithExecutionError_USERand the original code and message.A few notes:
SystemFailurescount behind.KindisUSER, since both codes mean the task spec or the workload is at fault rather than the platform. Easy to change if you'd rather they wereSYSTEM.systemErrorFromPhaseInfo, which flattens the code into the message text, soIsCausedBycan't see it. Noted in a comment where the codes are defined.MetadataTooLargeis not produced anywhere in the codebase today, so it's included defensively rather than tested against a real producer.CorruptedPluginStateis deliberately left out. It looks recoverable rather than deterministic, and I'd like to handle it separately. Details in a comment below.Why are the changes needed?
Follow-up to #7799, where we noticed the v2 executor doesn't check plugin error codes: every plugin error goes through
recordSystemErrorand is retried untilMaxSystemFailuresis exceeded, regardless of whether retrying could possibly help.Concretely, a typo in the Ray plugin config (
submissionMode: HttpMode) currently produces four attempts at 10-second intervals before failing, and reports asMaxSystemFailuresExceededrather than naming the actual problem. With this change it fails in about a second, and the failure carriesBadTaskSpecificationand the original message, which points at the config.How was this patch tested?
taskaction_controller_test.goasserting that aBadTaskSpecificationerror terminates immediately: no requeue,SystemFailuresstays zero, the user'sAttemptsbudget is untouched, andStatus.ErrorStatecarries the code,USERkind, and the original message.nonRetryableErrorCodesfor one the test doesn't use makes it fail.recordSystemErrorspecs still pass. They use a plain error with no typed code, so the new check correctly ignores them.