Skip to content

Commit f560680

Browse files
authored
Fix cancel before run (#94)
Closes #91
1 parent dae22ac commit f560680

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

temporalio/worker/workflow_instance.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,10 @@ def _apply_cancel_workflow(
352352
self._cancel_requested = True
353353
# TODO(cretz): Details or cancel message or whatever?
354354
if self._primary_task:
355-
self._primary_task.cancel()
355+
# The primary task may not have started yet and we want to give the
356+
# workflow the ability to receive the cancellation, so we must defer
357+
# this cancellation to the next iteration of the event loop.
358+
self.call_soon(self._primary_task.cancel)
356359

357360
def _apply_fire_timer(
358361
self, job: temporalio.bridge.proto.workflow_activation.FireTimer

tests/worker/test_workflow.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,31 @@ async def started() -> bool:
722722
assert isinstance(err.value.cause, CancelledError)
723723

724724

725+
@workflow.defn
726+
class TrapCancelWorkflow:
727+
@workflow.run
728+
async def run(self) -> str:
729+
try:
730+
await asyncio.Future()
731+
raise RuntimeError("should not get here")
732+
except asyncio.CancelledError:
733+
return "cancelled"
734+
735+
736+
async def test_workflow_cancel_before_run(client: Client):
737+
# Start the workflow _and_ send cancel before even starting the workflow
738+
task_queue = str(uuid.uuid4())
739+
handle = await client.start_workflow(
740+
TrapCancelWorkflow.run,
741+
id=f"workflow-{uuid.uuid4()}",
742+
task_queue=task_queue,
743+
)
744+
await handle.cancel()
745+
# Start worker and wait for result
746+
async with new_worker(client, TrapCancelWorkflow, task_queue=task_queue):
747+
assert "cancelled" == await handle.result()
748+
749+
725750
@activity.defn
726751
async def wait_forever() -> NoReturn:
727752
await asyncio.Future()

0 commit comments

Comments
 (0)