diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f7da4f30..d64a9658 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -17,7 +17,7 @@ jobs: go_latest: '1.28.1' typescript_latest: '1.10.3' java_latest: '1.25.0' - python_latest: '1.6.0' + python_latest: '1.7.0' csharp_latest: '1.2.0' steps: - run: 'echo noop' diff --git a/features/update/async_accepted/feature.py b/features/update/async_accepted/feature.py index 11e8e76f..d6b3ac94 100644 --- a/features/update/async_accepted/feature.py +++ b/features/update/async_accepted/feature.py @@ -2,7 +2,14 @@ from datetime import timedelta from temporalio import activity, workflow -from temporalio.client import RPCError, WorkflowHandle, WorkflowUpdateFailedError +from temporalio.client import ( + RPCError, + RPCStatusCode, + WorkflowHandle, + WorkflowUpdateFailedError, + WorkflowUpdateRPCTimeoutOrCancelledError, + WorkflowUpdateStage, +) from temporalio.exceptions import ApplicationError from harness.python.feature import Runner, register_feature @@ -51,7 +58,10 @@ async def check_result(runner: Runner, handle: WorkflowHandle) -> None: # Issue async update update_id = "sleepy_update" update_handle = await handle.start_update( - Workflow.do_maybe_wait_update, True, id=update_id + Workflow.do_maybe_wait_update, + True, + wait_for_stage=WorkflowUpdateStage.ACCEPTED, + id=update_id, ) await handle.signal(Workflow.unblock) # There's no API at the moment for directly creating a handle w/o calling start update since @@ -61,7 +71,10 @@ async def check_result(runner: Runner, handle: WorkflowHandle) -> None: # Async update which throws fail_update_id = "failing_update" update_handle = await handle.start_update( - Workflow.do_maybe_wait_update, False, id=fail_update_id + Workflow.do_maybe_wait_update, + False, + wait_for_stage=WorkflowUpdateStage.ACCEPTED, + id=fail_update_id, ) try: await update_handle.result() @@ -74,13 +87,16 @@ async def check_result(runner: Runner, handle: WorkflowHandle) -> None: # Verify timeouts work, but we can only use RPC timeout for now, because of ☝️ timeout_update_id = "timeout_update" update_handle = await handle.start_update( - Workflow.do_maybe_wait_update, True, id=timeout_update_id + Workflow.do_maybe_wait_update, + True, + wait_for_stage=WorkflowUpdateStage.ACCEPTED, + id=timeout_update_id, ) try: await update_handle.result(rpc_timeout=timedelta(seconds=1)) raise RuntimeError("Should have failed") - except RPCError as err: - assert "Timeout expired" == err.message + except WorkflowUpdateRPCTimeoutOrCancelledError: + pass await handle.signal(Workflow.finish) await handle.result() diff --git a/features/update/basic_async/feature.py b/features/update/basic_async/feature.py index f95589a5..516449c0 100644 --- a/features/update/basic_async/feature.py +++ b/features/update/basic_async/feature.py @@ -1,7 +1,11 @@ from datetime import timedelta from temporalio import workflow -from temporalio.client import WorkflowHandle, WorkflowUpdateFailedError +from temporalio.client import ( + WorkflowHandle, + WorkflowUpdateFailedError, + WorkflowUpdateStage, +) from harness.python.feature import Runner, register_feature @@ -35,7 +39,11 @@ def my_validate(self, arg: str): async def checker(runner: Runner, handle: WorkflowHandle): await runner.skip_if_update_unsupported() - bad_update_handle = await handle.start_update(Workflow.my_update, "bad-update-arg") + bad_update_handle = await handle.start_update( + Workflow.my_update, + "bad-update-arg", + wait_for_stage=WorkflowUpdateStage.ACCEPTED, + ) try: await bad_update_handle.result() except WorkflowUpdateFailedError: @@ -43,7 +51,11 @@ async def checker(runner: Runner, handle: WorkflowHandle): else: assert False, "Expected Update to be rejected due to validation failure" - update_handle = await handle.start_update(Workflow.my_update, "update-arg") + update_handle = await handle.start_update( + Workflow.my_update, + "update-arg", + wait_for_stage=WorkflowUpdateStage.ACCEPTED, + ) update_result = await update_handle.result() assert update_result == "update-result" result = await handle.result() diff --git a/features/update/deduplication/feature.py b/features/update/deduplication/feature.py index d3273d5d..b7805f17 100644 --- a/features/update/deduplication/feature.py +++ b/features/update/deduplication/feature.py @@ -2,7 +2,7 @@ from datetime import timedelta from temporalio import activity, workflow -from temporalio.client import WorkflowHandle +from temporalio.client import WorkflowHandle, WorkflowUpdateStage from harness.python.feature import Runner, register_feature @@ -37,15 +37,25 @@ async def start(runner: Runner) -> WorkflowHandle: async def check_result(runner: Runner, handle: WorkflowHandle) -> None: update_id = "incrementer" - h1 = await handle.start_update(Workflow.inc_counter, id=update_id) - h2 = await handle.start_update(Workflow.inc_counter, id=update_id) + h1 = await handle.start_update( + Workflow.inc_counter, + wait_for_stage=WorkflowUpdateStage.ACCEPTED, + id=update_id, + ) + h2 = await handle.start_update( + Workflow.inc_counter, + wait_for_stage=WorkflowUpdateStage.ACCEPTED, + id=update_id, + ) await handle.signal(Workflow.unblock) results = await asyncio.gather(h1.result(), h2.result()) assert results[0] == 1 assert results[1] == 1 # This only needs to start to unblock the workflow - await handle.start_update(Workflow.inc_counter) + await handle.start_update( + Workflow.inc_counter, wait_for_stage=WorkflowUpdateStage.ACCEPTED + ) # There should be two accepted updates, and only one of them should be completed with the set id total_updates = 0 diff --git a/poetry.lock b/poetry.lock index 1c3acf3f..3b3f4d99 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "black" version = "22.8.0" description = "The uncompromising code formatter." -category = "dev" optional = false python-versions = ">=3.6.2" files = [ @@ -51,7 +50,6 @@ uvloop = ["uvloop (>=0.15.2)"] name = "click" version = "8.1.3" description = "Composable command line interface toolkit" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -66,7 +64,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.5" description = "Cross-platform colored terminal text." -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -78,7 +75,6 @@ files = [ name = "isort" version = "5.10.1" description = "A Python utility / library to sort Python imports." -category = "dev" optional = false python-versions = ">=3.6.1,<4.0" files = [ @@ -96,7 +92,6 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"] name = "mypy" version = "0.961" description = "Optional static typing for Python" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -139,7 +134,6 @@ reports = ["lxml"] name = "mypy-extensions" version = "0.4.3" description = "Experimental type system extensions for programs checked with the mypy typechecker." -category = "dev" optional = false python-versions = "*" files = [ @@ -151,7 +145,6 @@ files = [ name = "pathspec" version = "0.10.1" description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -163,7 +156,6 @@ files = [ name = "platformdirs" version = "2.5.2" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -179,7 +171,6 @@ test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock name = "protobuf" version = "4.21.6" description = "" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -203,7 +194,6 @@ files = [ name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -218,7 +208,6 @@ six = ">=1.5" name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -228,18 +217,17 @@ files = [ [[package]] name = "temporalio" -version = "1.6.0" +version = "1.7.0" description = "Temporal.io Python SDK" -category = "main" optional = false python-versions = "<4.0,>=3.8" files = [ - {file = "temporalio-1.6.0-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:50207806c5b9d701226ed2aed1fce44c688225ab9a370b014b06e51872b98ea7"}, - {file = "temporalio-1.6.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:499253385dd3ca1827d34a05ae61350d54040e0d6a11502f04cbafa7b35be114"}, - {file = "temporalio-1.6.0-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8fb097b97f833483cd500af2460a0996f812e8019327d893844a21b1c7cd9868"}, - {file = "temporalio-1.6.0-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6b25d451170ecdf8443f1ed09f75ea708e8679c26636e7aa326bc89bd6bd0c84"}, - {file = "temporalio-1.6.0-cp38-abi3-win_amd64.whl", hash = "sha256:b5ae0bea0665a0bc87d80e7d18870b32eec631694abc0610ee39235e99cc304b"}, - {file = "temporalio-1.6.0.tar.gz", hash = "sha256:a6f24ea91eb1dd1345c68f4ceb21dd2a11a84cda0d6d963d6e570a0c156a80f0"}, + {file = "temporalio-1.7.0-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:92ec0a1af8d4b41245df339a422f1f87367742d9638d2dba7bb7d3ab934e7f5d"}, + {file = "temporalio-1.7.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:8b4bb77d766a2ac1d85f3e9b682658fee67d77e87f73bd256d46cd79ecf767f6"}, + {file = "temporalio-1.7.0-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a38dd43061666700500d5808c18ec0b0f569504a2f22b99d7c38dc4dc50b21fd"}, + {file = "temporalio-1.7.0-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e0087fb6cdb9e9b8aa62c1705526947cb00a91159435d294f3da0d92b501ed56"}, + {file = "temporalio-1.7.0-cp38-abi3-win_amd64.whl", hash = "sha256:eb45b751c6f7946dccba29260922f0e7192b28b8fb9e2aa5afc2aaf5157891d9"}, + {file = "temporalio-1.7.0.tar.gz", hash = "sha256:5057b74df644bd4f5f4eb0e95e730a0a36a16f7ee926d36fcd479c223a7c63cd"}, ] [package.dependencies] @@ -256,7 +244,6 @@ opentelemetry = ["opentelemetry-api (>=1.11.1,<2.0.0)", "opentelemetry-sdk (>=1. name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -268,7 +255,6 @@ files = [ name = "types-protobuf" version = "3.20.4" description = "Typing stubs for protobuf" -category = "main" optional = false python-versions = "*" files = [ @@ -280,7 +266,6 @@ files = [ name = "typing-extensions" version = "4.3.0" description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -291,4 +276,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "48bca8fa0ffb84367188fa1737198f3e1731728f1c28a30d94c778ae5b58e6d7" +content-hash = "0760467644f53355d803d932556d4cc925805910e8bcba026d76963b6224d364" diff --git a/pyproject.toml b/pyproject.toml index 5503de30..f5b5a49c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ packages = [ [tool.poetry.dependencies] python = "^3.8" -temporalio = "^1.6.0" +temporalio = "^1.7.0" [tool.poetry.dev-dependencies] mypy = "^0.961"