|
33 | 33 |
|
34 | 34 | logger = logging.getLogger(__name__) |
35 | 35 | EventHandler = Callable[[core_event.Event], Awaitable[Any]] |
| 36 | +LoopStartedHandler = Callable[[], Awaitable[Any]] |
36 | 37 |
|
37 | 38 |
|
38 | 39 | # Indices for prefetched event tuples stored in the EventMultiplexer heap. |
@@ -114,6 +115,7 @@ def __init__(self, max_concurrent: int): |
114 | 115 | self._event_handlers: Dict[core_event.EventSource, List[EventHandler]] = defaultdict(list) |
115 | 116 | self._sniffers_pre: List[EventHandler] = [] |
116 | 117 | self._sniffers_post: List[EventHandler] = [] |
| 118 | + self._loop_started_handlers: List[LoopStartedHandler] = [] |
117 | 119 | self._producers: Set[core_event.Producer] = set() |
118 | 120 | # Task group for core tasks like producers and dispatch loop. |
119 | 121 | self._core_tasks: Optional[helpers.TaskGroup] = None |
@@ -179,6 +181,17 @@ def subscribe_all(self, event_handler: EventHandler, front_run: bool = False): |
179 | 181 | if event_handler not in sniffers: |
180 | 182 | sniffers.append(event_handler) |
181 | 183 |
|
| 184 | + def subscribe_event_loop_started(self, handler: LoopStartedHandler): |
| 185 | + """Registers an async callable that will be called once when the event loop starts. |
| 186 | +
|
| 187 | + :param handler: An async callable that receives no arguments. |
| 188 | + """ |
| 189 | + |
| 190 | + assert not self._running, "Subscribing once we're running is not currently supported." |
| 191 | + |
| 192 | + if handler not in self._loop_started_handlers: |
| 193 | + self._loop_started_handlers.append(handler) |
| 194 | + |
182 | 195 | def schedule(self, when: datetime.datetime, job: SchedulerJob): |
183 | 196 | """Schedules a function to be executed at a given time. |
184 | 197 |
|
@@ -248,6 +261,10 @@ async def _core_task_group(self): |
248 | 261 | finally: |
249 | 262 | self._core_tasks = None |
250 | 263 |
|
| 264 | + async def _notify_loop_started(self): |
| 265 | + if self._loop_started_handlers: |
| 266 | + await gather_no_raise(*[handler() for handler in self._loop_started_handlers]) |
| 267 | + |
251 | 268 | async def _dispatch_event(self, event: core_event.Event, handlers: List[EventHandler]): |
252 | 269 | if self._debug_enabled: |
253 | 270 | logger.debug(logs.StructuredMessage( |
|
0 commit comments