@@ -13,28 +13,27 @@ def auto_heartbeater(fn: F) -> F:
1313 # available via our wrapper, so we use the functools wraps decorator
1414 @wraps (fn )
1515 async def wrapper (* args , ** kwargs ):
16- done = asyncio .Event ()
17- # Heartbeat twice as often as the timeout
1816 heartbeat_timeout = activity .info ().heartbeat_timeout
17+ heartbeat_task = None
1918 if heartbeat_timeout :
20- asyncio .create_task (
21- heartbeat_every (heartbeat_timeout .total_seconds () / 2 , done )
19+ # Heartbeat twice as often as the timeout
20+ heartbeat_task = asyncio .create_task (
21+ heartbeat_every (heartbeat_timeout .total_seconds () / 2 )
2222 )
2323 try :
2424 return await fn (* args , ** kwargs )
2525 finally :
26- done .set ()
26+ if heartbeat_task :
27+ heartbeat_task .cancel ()
28+ # Wait for heartbeat cancellation to complete
29+ await asyncio .wait ([heartbeat_task ])
2730
2831 return cast (F , wrapper )
2932
3033
31- async def heartbeat_every (
32- delay : float , done_event : asyncio .Event , * details : Any
33- ) -> None :
34+ async def heartbeat_every (delay : float , * details : Any ) -> None :
3435 # Heartbeat every so often while not cancelled
35- while not done_event .is_set ():
36- try :
37- await asyncio .wait_for (done_event .wait (), delay )
38- except asyncio .TimeoutError :
39- print (f"Heartbeating at { datetime .now ()} " )
40- activity .heartbeat (* details )
36+ while True :
37+ await asyncio .sleep (delay )
38+ print (f"Heartbeating at { datetime .now ()} " )
39+ activity .heartbeat (* details )
0 commit comments