Example #1
0
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
Example #2
0
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)
Example #3
0
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)
Example #4
0
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 []
Example #5
0
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
Example #6
0
def _create_startup_root_task(
    *,
    name: str,
    coro: Coroutine[Any, Any, Any],
) -> asyncio_Task:
    return backports.create_task(coro=coro, name=name)