Repository navigation
Decode deadline callback kwargs where the callback runs - #74830
Conversation
Deadline Alert callback kwargs were decoded in the scheduler and the API server whenever deadline alerts were loaded, although neither component calls the callback. Keep the kwargs serde-encoded on the server and decode them where they are used: the triggerer decodes AsyncCallback kwargs with its existing pipeline, and the callback subprocess decodes SyncCallback kwargs right before calling the user callable. Executor callback data now carries a "kwargs_encoding" marker so the worker only decodes encoded kwargs, callbacks created before upgrade run unchanged, and an older Task SDK fails such callbacks instead of passing encoded arguments. The runtime-provided callback context is serialized strictly, as before; only the stored callback kwargs keep their encoded form. Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions
bd82fc1 to
1f44532
Compare
Deadline callback kwargs are now kept in their encoded form, so metric tags and the callback repr showed the raw encoding instead of the values. Show them in a readable form again, without importing or building anything they name. Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions
A timedelta payload holding NaN made the display of callback kwargs raise, which would escape from metric emission and the callback repr. Show such values, and any other interval that cannot be built, in the generic form instead. Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions
… it is refused The triggerer-path deadline test pinned the AttributeError raised by strict serialization. Assert the outcome instead (no trigger is created and nothing in the context is constructed), so the test holds whether the context is refused by raising or by failing the callback. Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions
|
@ferruzzi @ramitkataria Could you take a look at this when you have a moment? It's targeted at 3.4.0 and needs a review to make the cut on 2026-10-19. CI is green. |
Generated-by: Claude Opus 5
There was a problem hiding this comment.
Looks good to me. Callback kwargs stay encoded on the server and are decoded where the callback runs, the encoding marker keeps callbacks created before the upgrade working, and the triggerer now fails a single undecodable trigger instead of stopping the runner. Could use reviews from @ferruzzi @ramitkataria before merging.
Backport successfully created: v3-4-testNote: As of Merging PRs targeted for Airflow 3.X In matter of doubt please ask in #release-management Slack channel.
|
…74830) (#75114) * Decode deadline callback kwargs where the callback runs Deadline Alert callback kwargs were decoded in the scheduler and the API server whenever deadline alerts were loaded, although neither component calls the callback. Keep the kwargs serde-encoded on the server and decode them where they are used: the triggerer decodes AsyncCallback kwargs with its existing pipeline, and the callback subprocess decodes SyncCallback kwargs right before calling the user callable. Executor callback data now carries a "kwargs_encoding" marker so the worker only decodes encoded kwargs, callbacks created before upgrade run unchanged, and an older Task SDK fails such callbacks instead of passing encoded arguments. The runtime-provided callback context is serialized strictly, as before; only the stored callback kwargs keep their encoded form. Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions * Render deadline callback kwargs readably in metrics and repr Deadline callback kwargs are now kept in their encoded form, so metric tags and the callback repr showed the raw encoding instead of the values. Show them in a readable form again, without importing or building anything they name. Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions * Keep deadline callback kwargs display total for non-finite intervals A timedelta payload holding NaN made the display of callback kwargs raise, which would escape from metric emission and the callback repr. Show such values, and any other interval that cannot be built, in the generic form instead. Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions * Assert that the deadline context never reaches the triggerer, not how it is refused The triggerer-path deadline test pinned the AttributeError raised by strict serialization. Assert the outcome instead (no trigger is created and nothing in the context is constructed), so the test holds whether the context is refused by raising or by failing the callback. Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions * Fail only the affected trigger when its kwargs cannot be decoded (cherry picked from commit 233f9c3) Generated-by: Claude Opus 5 Co-authored-by: Jarek Potiuk <jarek@potiuk.com>
…74830) (#75114) * Decode deadline callback kwargs where the callback runs Deadline Alert callback kwargs were decoded in the scheduler and the API server whenever deadline alerts were loaded, although neither component calls the callback. Keep the kwargs serde-encoded on the server and decode them where they are used: the triggerer decodes AsyncCallback kwargs with its existing pipeline, and the callback subprocess decodes SyncCallback kwargs right before calling the user callable. Executor callback data now carries a "kwargs_encoding" marker so the worker only decodes encoded kwargs, callbacks created before upgrade run unchanged, and an older Task SDK fails such callbacks instead of passing encoded arguments. The runtime-provided callback context is serialized strictly, as before; only the stored callback kwargs keep their encoded form. Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions * Render deadline callback kwargs readably in metrics and repr Deadline callback kwargs are now kept in their encoded form, so metric tags and the callback repr showed the raw encoding instead of the values. Show them in a readable form again, without importing or building anything they name. Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions * Keep deadline callback kwargs display total for non-finite intervals A timedelta payload holding NaN made the display of callback kwargs raise, which would escape from metric emission and the callback repr. Show such values, and any other interval that cannot be built, in the generic form instead. Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions * Assert that the deadline context never reaches the triggerer, not how it is refused The triggerer-path deadline test pinned the AttributeError raised by strict serialization. Assert the outcome instead (no trigger is created and nothing in the context is constructed), so the test holds whether the context is refused by raising or by failing the callback. Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions * Fail only the affected trigger when its kwargs cannot be decoded (cherry picked from commit 233f9c3) Generated-by: Claude Opus 5 Co-authored-by: Jarek Potiuk <jarek@potiuk.com>
|
@potiuk I’m actually not sure whether this change might lead to any issues: (Apologies for the tag – I just saw this change and realized that it is part of 3.4.0.) |
Deadline Alert callback
kwargswere decoded in the scheduler and the API server whenever aserialized Dag's deadline alerts were loaded. Neither component calls the callback: the decoded
callback is only used to pick the callback model by type and to copy
serialize()back intoCallback.data, which is an identity round-trip. Decoding there means constructing user objectsin components that never use them, and it is also lossy for sync callbacks, whose kwargs went
through
BaseSerializationand a JSON workload before reaching the worker.This keeps the kwargs in their serde-encoded form on the server and decodes them at the point
of use, on both consumption paths:
_decode_deadline_callbackkeepskwargsencoded (only a legacy{"__type": "dict", "__var": ...}container is unwrapped). Re-encoding a decodedSerializedDeadlineAlertwrites them back unchanged instead of serializing them again.TriggererCallback.queuestores the encoded kwargs on thetrigger row as-is via a new
Trigger.from_serialized_kwargs, giving the same stored form asbefore. The triggerer decodes them with its existing pipeline when it creates the
CallbackTrigger, so the triggerer itself is unchanged.execute_callbackdecodes the kwargs in the callback subprocessright before calling the user callable. The scheduler-provided
contextis passed through."kwargs_encoding": "serde".BaseExecutor.run_workloadpasses it tosupervise_callbackonlywhen set, and the Task SDK decodes the kwargs only when it is present, so callbacks created
before upgrade (no marker, already-decoded kwargs) run unchanged. A worker with an upgraded
apache-airflowand an older Task SDK fails such callbacks with an error instead of runningthem with encoded arguments. Workers should upgrade
apache-airflowandapache-airflow-task-sdktogether; see the significant newsfragment.Both the current serde encoding and the legacy
{"__type", "__var"}encoding are handled, andCallback rows created before upgrade (holding already-decoded kwargs) keep working on both paths.
Tests cover:
byte-identically;
CallbackTriggerbuilt the way the triggererbuilds it;
store -> workload JSON ->
execute_callbackround-trip;unknown marker fails the callback;
The test that asserted the previous decode-on-load behaviour is replaced.
Was generative AI tooling used to co-author this PR?
Generated-by: Claude Opus 5 following the guidelines
{pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.