33import logging .handlers
44import queue
55import socket
6+ import threading
67import time
78import uuid
89from collections .abc import Awaitable , Callable , Iterator , Sequence
@@ -265,8 +266,28 @@ async def get_pending_activity_info(
265266 return None
266267
267268
269+ _wait_for_pause_events : dict [str , threading .Event ] = {}
270+
271+
272+ def wait_for_pause_event (activity_id : str ) -> None :
273+ event = _wait_for_pause_events .get (activity_id )
274+ if event is not None :
275+ event .wait ()
276+
277+
278+ async def async_wait_for_pause_event (activity_id : str ) -> None :
279+ event = _wait_for_pause_events .get (activity_id )
280+ if event is not None :
281+ await asyncio .get_running_loop ().run_in_executor (None , event .wait )
282+
283+
268284async def pause_and_assert (client : Client , handle : WorkflowHandle , activity_id : str ):
269- """Pause the given activity and assert it becomes paused."""
285+ """Pause the given activity and assert it becomes paused.
286+
287+ Registers an event before calling the pause API so cooperating test
288+ activities (those that catch the pause-induced cancel via
289+ wait_for_pause_release) hang until we have observed paused=true.
290+ """
270291 desc = await handle .describe ()
271292 req = PauseActivityRequest (
272293 namespace = client .namespace ,
@@ -276,14 +297,19 @@ async def pause_and_assert(client: Client, handle: WorkflowHandle, activity_id:
276297 ),
277298 id = activity_id ,
278299 )
279- await client .workflow_service .pause_activity (req )
280300
281- # Assert eventually paused
282- async def check_paused () -> bool :
283- info = await assert_pending_activity_exists_eventually (handle , activity_id )
284- return info .paused
301+ _wait_for_pause_events [activity_id ] = threading .Event ()
302+ try :
303+ await client .workflow_service .pause_activity (req )
304+
305+ async def check_paused () -> None :
306+ info = await assert_pending_activity_exists_eventually (handle , activity_id )
307+ assert info .paused , f"Activity { activity_id } not yet paused"
285308
286- await assert_eventually (check_paused )
309+ await assert_eventually (check_paused )
310+ finally :
311+ _wait_for_pause_events [activity_id ].set ()
312+ del _wait_for_pause_events [activity_id ]
287313
288314
289315async def unpause_and_assert (client : Client , handle : WorkflowHandle , activity_id : str ):
@@ -300,9 +326,9 @@ async def unpause_and_assert(client: Client, handle: WorkflowHandle, activity_id
300326 await client .workflow_service .unpause_activity (req )
301327
302328 # Assert eventually not paused
303- async def check_unpaused () -> bool :
329+ async def check_unpaused () -> None :
304330 info = await assert_pending_activity_exists_eventually (handle , activity_id )
305- return not info .paused
331+ assert not info .paused , f"Activity { activity_id } still paused"
306332
307333 await assert_eventually (check_unpaused )
308334
0 commit comments