File tree Expand file tree Collapse file tree 2 files changed +29
-1
lines changed
Expand file tree Collapse file tree 2 files changed +29
-1
lines changed Original file line number Diff line number Diff 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
Original file line number Diff line number Diff 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
726751async def wait_forever () -> NoReturn :
727752 await asyncio .Future ()
You can’t perform that action at this time.
0 commit comments