async def test_py37_create_task_accepts_name(mocker): real_create_task = mocker.patch('asyncio.create_task') coro = sample() task = create_task(coro, name='unused') assert real_create_task.called assert task is real_create_task.return_value await coro # to prevent "never awaited" errors
async def _stop_flag_checker( signal_flag: asyncio_Future, stop_flag: Optional[primitives.Flag], ) -> None: """ A top-level task for external stopping by setting a stop-flag. Once set, this task will exit, and thus all other top-level tasks will be cancelled. """ # Selects the flags to be awaited (if set). flags = [] if signal_flag is not None: flags.append(signal_flag) if stop_flag is not None: flags.append( backports.create_task(primitives.wait_flag(stop_flag), name="stop-flag waiter")) # Wait until one of the stoppers is set/raised. try: done, pending = await asyncio.wait(flags, return_when=asyncio.FIRST_COMPLETED) future = done.pop() result = await future except asyncio.CancelledError: pass # operator is stopping for any other reason else: if result is None: logger.info("Stop-flag is raised. Operator is stopping.") elif isinstance(result, signal.Signals): logger.info("Signal %s is received. Operator is stopping.", result.name) else: logger.info("Stop-flag is set to %r. Operator is stopping.", result)
def _create_checked_root_task( *, name: str, coro: Coroutine[Any, Any, Any], ready_flag: primitives.Flag, ) -> asyncio_Task: return backports.create_task(_root_task_checker( ready_flag=ready_flag, name=name, coro=coro, ), name=name)
async def spawn_resource_daemons( *, settings: configuration.OperatorSettings, handlers: Sequence[handlers_.ResourceSpawningHandler], daemons: MutableMapping[handlers_.HandlerId, containers.Daemon], cause: causation.ResourceSpawningCause, memory: containers.ResourceMemory, ) -> Collection[float]: """ Ensure that all daemons are spawned for this individual resource. This function can be called multiple times on multiple handling cycles (though usually should be called on the first-seen occasion), so it must be idempotent: not having duplicating side-effects on multiple calls. """ if memory.live_fresh_body is None: # for type-checking; "not None" is ensured in processing. raise RuntimeError( "A daemon is spawned with None as body. This is a bug. Please report." ) for handler in handlers: if handler.id not in daemons: stopper = primitives.DaemonStopper() daemon_cause = causation.DaemonCause( resource=cause.resource, logger=cause.logger, body=memory.live_fresh_body, memo=memory.memo, patch=patches.Patch( ), # not the same as the one-shot spawning patch! stopper=stopper, # for checking (passed to kwargs) ) daemon = containers.Daemon( stopper=stopper, # for stopping (outside of causes) handler=handler, logger=loggers.LocalObjectLogger(body=cause.body, settings=settings), task=backports.create_task( _runner( settings=settings, daemons=daemons, # for self-garbage-collection handler=handler, cause=daemon_cause, memory=memory, ), name=f'runner of {handler.id}' ), # sometimes, daemons; sometimes, timers. ) daemons[handler.id] = daemon return []
async def streaming_watch( *, settings: configuration.OperatorSettings, resource: resources.Resource, namespace: Optional[str], freeze_mode: Optional[primitives.Toggle] = None, ) -> AsyncIterator[bodies.RawEvent]: # Prevent both watching and listing while the freeze mode is on, until it is off. # Specifically, the watch-stream closes its connection once the freeze mode is on, # so the while-true & for-event-in-stream cycles exit, and this coroutine is started # again by the `infinite_stream()` (the watcher timeout is swallowed by the freeze time). if freeze_mode is not None and freeze_mode.is_on(): logger.debug("Freezing the watch-stream for %r", resource) await freeze_mode.wait_for_off() logger.debug("Resuming the watch-stream for %r", resource) # A stop-feature is a client-specific way of terminating the streaming HTTPS connection # when a freeze-mode is turned on. The low-level API call attaches its `response.close()` # to the future's callbacks, and a background task triggers it when the mode is turned on. freeze_waiter: asyncio_Future if freeze_mode is not None: freeze_waiter = backports.create_task( freeze_mode.wait_for_on(), name= f'freeze-waiter for {resource.name} @ {namespace or "cluster-wide"}' ) else: freeze_waiter = asyncio.Future() # a dummy just ot have it try: stream = continuous_watch( settings=settings, resource=resource, namespace=namespace, freeze_waiter=freeze_waiter, ) async for raw_event in stream: yield raw_event finally: with contextlib.suppress(asyncio.CancelledError): freeze_waiter.cancel() await freeze_waiter
def _create_startup_root_task( *, name: str, coro: Coroutine[Any, Any, Any], ) -> asyncio_Task: return backports.create_task(coro=coro, name=name)