From d3c1aa333e2a7666a5e1dffe45594719e9102a61 Mon Sep 17 00:00:00 2001 From: Raphael Fakhri <153192858+RaphaelFakhri@users.noreply.github.com> Date: Thu, 22 Oct 2026 12:26:13 +0000 Subject: [PATCH] Send a request ID when terminating a standalone activity --- changelog/fixed/tiptoeing-terrapin.md | 1 + temporalio/client/_impl.py | 1 + tests/test_activity.py | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 changelog/fixed/tiptoeing-terrapin.md diff --git a/changelog/fixed/tiptoeing-terrapin.md b/changelog/fixed/tiptoeing-terrapin.md new file mode 100644 index 0000000000..6d5bcc7181 --- /dev/null +++ b/changelog/fixed/tiptoeing-terrapin.md @@ -0,0 +1 @@ +Send a request ID when terminating a standalone activity, so a retried `ActivityHandle.terminate()` call no longer fails after the first attempt already terminated the activity. diff --git a/temporalio/client/_impl.py b/temporalio/client/_impl.py index a5103f61d3..76526f268b 100644 --- a/temporalio/client/_impl.py +++ b/temporalio/client/_impl.py @@ -687,6 +687,7 @@ async def terminate_activity(self, input: TerminateActivityInput) -> None: run_id=input.activity_run_id or "", reason=input.reason or "", identity=self._client.identity, + request_id=str(uuid.uuid4()), ), retry=True, metadata=input.rpc_metadata, diff --git a/tests/test_activity.py b/tests/test_activity.py index b3208d951d..b17d587d85 100644 --- a/tests/test_activity.py +++ b/tests/test_activity.py @@ -112,6 +112,25 @@ async def test_start_activity_generates_request_id() -> None: assert requests[0].request_id != requests[1].request_id +async def test_terminate_activity_generates_request_id() -> None: + terminate_activity_execution = mock.AsyncMock( + return_value=temporalio.api.workflowservice.v1.TerminateActivityExecutionResponse() + ) + service_client = mock.MagicMock() + service_client.config.identity = "test-identity" + service_client.workflow_service.terminate_activity_execution = ( + terminate_activity_execution + ) + client = Client(service_client) + + for activity_id in ("activity-id-1", "activity-id-2"): + await client.get_activity_handle(activity_id).terminate(reason="done") + + requests = [call.args[0] for call in terminate_activity_execution.call_args_list] + assert all(uuid.UUID(request.request_id).version == 4 for request in requests) + assert requests[0].request_id != requests[1].request_id + + class TestDescribe: @pytest.fixture def task_queue(self):