Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 17.7k
AIP-103: Worker side custom state backend support#66859
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
amoghrajesh
merged 22 commits into
apache:main
from
astronomer:aip-103-5-workers-state-backendMay 20, 2026
Uh oh!
There was an error while loading. Please reload this page.
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
68d0262
execution API endpoints and datamodel
amoghrajesh e2e16ea
shared lib changes
amoghrajesh 36de8cb
task sdk: api client changes
amoghrajesh bc94b1c
task sdk: supervisor changes
amoghrajesh 8b19c09
task sdk: conf changes
amoghrajesh 0656cef
task sdk: context accessor changes
amoghrajesh 75156c4
task sdk: task runner changes
amoghrajesh 2a03058
Merge branch 'main' into aip-103-5-workers-state-backend
amoghrajesh 8d29dc4
removing wrongly committed file
amoghrajesh 867dc7f
fixing CI failures
amoghrajesh 432b432
ultimate change to simplify workers backend
amoghrajesh 57437c6
ultimate undo of things
amoghrajesh 6e7a00e
cleaning up things
amoghrajesh 5489844
cleaning up things
amoghrajesh dd53551
fixing tests
amoghrajesh 6db9bc3
comments from wei
amoghrajesh 167826f
fixing shared tests
amoghrajesh 3bab433
Merge branch 'main' into aip-103-5-workers-state-backend
amoghrajesh 99e4c3b
uncommenting old comments and cleaning up
amoghrajesh b78f338
comments from jason
amoghrajesh 4ce6909
fixing tests
amoghrajesh 59e33f7
handling review comments from kaxil
amoghrajesh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -18,7 +18,22 @@ | ||
| import pytest | ||
| from airflow_shared.state import BaseStateBackend, StateScope | ||
| from airflow_shared.state import AssetScope, BaseStateBackend, StateScope | ||
| class TestAssetScope: | ||
| def test_requires_at_least_one_identifier(self): | ||
| with pytest.raises(ValueError, match="at least one of"): | ||
| AssetScope() | ||
| def test_asset_id_alone_is_valid(self): | ||
| AssetScope(asset_id=1) | ||
| def test_name_alone_is_valid(self): | ||
| AssetScope(name="my_asset") | ||
| def test_uri_alone_is_valid(self): | ||
| AssetScope(uri="s3://bucket/key") | ||
| class TestBaseStateBackend: | ||
| @@ -70,3 +85,69 @@ def test_abstract_methods_cover_full_interface(self): | ||
| """BaseStateBackend enforces all 8 sync+async methods as abstract.""" | ||
| expected = {"get", "set", "delete", "clear", "aget", "aset", "adelete", "aclear"} | ||
| assert BaseStateBackend.__abstractmethods__ == expected | ||
| def test_task_state_serialize_deserialize_round_trip(self, backend): | ||
| original = "app_1234" | ||
| serialized = backend.serialize_task_state_to_ref(value=original, key="job_id", ti_id="abc-123") | ||
| deserialized = backend.deserialize_task_state_from_ref(serialized) | ||
| assert deserialized == original | ||
| def test_custom_backend_overrides_task_state_ser_deser(self): | ||
| class MyBackend(BaseStateBackend): | ||
| def get(self, scope, key): ... | ||
| def set(self, scope, key, value): ... | ||
| def delete(self, scope, key): ... | ||
| def clear(self, scope, *, all_map_indices=False): ... | ||
| async def aget(self, scope, key): ... | ||
| async def aset(self, scope, key, value): ... | ||
| async def adelete(self, scope, key): ... | ||
| async def aclear(self, scope, *, all_map_indices=False): ... | ||
| def serialize_task_state_to_ref(self, *, value, key, ti_id): | ||
| return f"s3://bucket/{ti_id}/{key}" | ||
| def deserialize_task_state_from_ref(self, stored): | ||
| return f"fetched:{stored}" | ||
| b = MyBackend() | ||
| assert b.serialize_task_state_to_ref(value="app_1234", key="job_id", ti_id="abc-123") == ( | ||
| "s3://bucket/abc-123/job_id" | ||
| ) | ||
| assert ( | ||
| b.deserialize_task_state_from_ref("s3://bucket/abc-123/job_id") | ||
| == "fetched:s3://bucket/abc-123/job_id" | ||
| ) | ||
| def test_asset_state_serialize_deserialize_round_trip(self, backend): | ||
| original = "2026-05-01" | ||
| serialized = backend.serialize_asset_state_to_ref( | ||
| value="2026-05-01", key="watermark", asset_ref="my_asset" | ||
| ) | ||
| deserialized = backend.deserialize_asset_state_from_ref(serialized) | ||
| assert deserialized == original | ||
| def test_custom_backend_overrides_asset_state_ser_deser(self): | ||
| class MyBackend(BaseStateBackend): | ||
| def get(self, scope, key): ... | ||
| def set(self, scope, key, value): ... | ||
| def delete(self, scope, key): ... | ||
| def clear(self, scope, *, all_map_indices=False): ... | ||
| async def aget(self, scope, key): ... | ||
| async def aset(self, scope, key, value): ... | ||
| async def adelete(self, scope, key): ... | ||
| async def aclear(self, scope, *, all_map_indices=False): ... | ||
| def serialize_asset_state_to_ref(self, *, value, key, asset_ref): | ||
| return f"s3://bucket/assets/{asset_ref}/{key}" | ||
amoghrajesh marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| def deserialize_asset_state_from_ref(self, stored): | ||
| return f"resolved:{stored}" | ||
| b = MyBackend() | ||
| assert b.serialize_asset_state_to_ref(value="2026-05-01", key="watermark", asset_ref="my_asset") == ( | ||
| "s3://bucket/assets/my_asset/watermark" | ||
| ) | ||
| assert ( | ||
| b.deserialize_asset_state_from_ref("s3://bucket/assets/my_asset/watermark") | ||
| == "resolved:s3://bucket/assets/my_asset/watermark" | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ../../../../../shared/state/src/airflow_shared/state |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Oops, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.