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(
352
352
self ._cancel_requested = True
353
353
# TODO(cretz): Details or cancel message or whatever?
354
354
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 )
356
359
357
360
def _apply_fire_timer (
358
361
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:
722
722
assert isinstance (err .value .cause , CancelledError )
723
723
724
724
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
+
725
750
@activity .defn
726
751
async def wait_forever () -> NoReturn :
727
752
await asyncio .Future ()
You can’t perform that action at this time.
0 commit comments