@@ -1206,44 +1206,49 @@ async def reboot(
12061206 self .log .debug ('Actor is already rebooting, skipping the additional reboot call.' )
12071207 return
12081208
1209- self ._is_rebooting = True
1209+ if not self .configuration .actor_run_id :
1210+ raise RuntimeError ('actor_run_id cannot be None when running on the Apify platform.' )
12101211
1211- if not custom_after_sleep :
1212+ if custom_after_sleep is None :
12121213 custom_after_sleep = self .configuration .metamorph_after_sleep
12131214
1214- # Call all the listeners for the PERSIST_STATE and MIGRATING events, and wait for them to finish.
1215- # PERSIST_STATE listeners are called to allow the Actor to persist its state before the reboot.
1216- # MIGRATING listeners are called to allow the Actor to gracefully stop in-progress tasks before the reboot.
1217- # Typically, crawlers are listening for the MIIGRATING event to stop processing new requests.
1218- # We can't just emit the events and wait for all listeners to finish,
1219- # because this method might be called from an event listener itself, and we would deadlock.
1220- persist_state_listeners = flatten (
1221- (self .event_manager ._listeners_to_wrappers [Event .PERSIST_STATE ] or {}).values () # noqa: SLF001
1222- )
1223- migrating_listeners = flatten (
1224- (self .event_manager ._listeners_to_wrappers [Event .MIGRATING ] or {}).values () # noqa: SLF001
1225- )
1226-
1227- async def safe_dispatch (listener : Any , data : Any ) -> None :
1228- try :
1229- await listener (data )
1230- except Exception :
1231- self .log .exception ('A pre-reboot event listener failed' )
1215+ self ._is_rebooting = True
12321216
1233- timeout = event_listeners_timeout .total_seconds () if event_listeners_timeout else None
12341217 try :
1235- async with asyncio .timeout (timeout ), asyncio .TaskGroup () as tg :
1236- for listener in persist_state_listeners :
1237- tg .create_task (safe_dispatch (listener , EventPersistStateData (is_migrating = True )))
1238- for listener in migrating_listeners :
1239- tg .create_task (safe_dispatch (listener , EventMigratingData ()))
1240- except TimeoutError :
1241- self .log .warning ('Pre-reboot event listeners did not finish within timeout; proceeding with reboot' )
1218+ # Call all the listeners for the PERSIST_STATE and MIGRATING events, and wait for them to finish.
1219+ # PERSIST_STATE listeners are called to allow the Actor to persist its state before the reboot.
1220+ # MIGRATING listeners are called to allow the Actor to gracefully stop in-progress tasks before
1221+ # the reboot. Typically, crawlers are listening for the MIIGRATING event to stop processing new requests.
1222+ # We can't just emit the events and wait for all listeners to finish,
1223+ # because this method might be called from an event listener itself, and we would deadlock.
1224+ persist_state_listeners = flatten (
1225+ (self .event_manager ._listeners_to_wrappers [Event .PERSIST_STATE ] or {}).values () # noqa: SLF001
1226+ )
1227+ migrating_listeners = flatten (
1228+ (self .event_manager ._listeners_to_wrappers [Event .MIGRATING ] or {}).values () # noqa: SLF001
1229+ )
12421230
1243- if not self .configuration .actor_run_id :
1244- raise RuntimeError ('actor_run_id cannot be None when running on the Apify platform.' )
1231+ async def safe_dispatch (listener : Any , data : Any ) -> None :
1232+ try :
1233+ await listener (data )
1234+ except Exception :
1235+ self .log .exception ('A pre-reboot event listener failed' )
12451236
1246- await self .apify_client .run (self .configuration .actor_run_id ).reboot ()
1237+ timeout = event_listeners_timeout .total_seconds () if event_listeners_timeout else None
1238+ try :
1239+ async with asyncio .timeout (timeout ), asyncio .TaskGroup () as tg :
1240+ for listener in persist_state_listeners :
1241+ tg .create_task (safe_dispatch (listener , EventPersistStateData (is_migrating = True )))
1242+ for listener in migrating_listeners :
1243+ tg .create_task (safe_dispatch (listener , EventMigratingData ()))
1244+ except TimeoutError :
1245+ self .log .warning ('Pre-reboot event listeners did not finish within timeout; proceeding with reboot' )
1246+
1247+ await self .apify_client .run (self .configuration .actor_run_id ).reboot ()
1248+ except BaseException :
1249+ # Reset the flag so that a failed or cancelled reboot can be retried.
1250+ self ._is_rebooting = False
1251+ raise
12471252
12481253 if custom_after_sleep :
12491254 await asyncio .sleep (custom_after_sleep .total_seconds ())
0 commit comments