Skip to content

Commit

Permalink
Revert services.py partially to 0.2.1 to fix bugs (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
wbarnha authored Nov 30, 2022
1 parent 024112a commit 030d69f
Showing 1 changed file with 35 additions and 25 deletions.
60 changes: 35 additions & 25 deletions mode/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,19 @@
import asyncio
import logging
import sys
from asyncio.locks import Event
from contextlib import AsyncExitStack, ExitStack
from datetime import tzinfo
from functools import wraps
from time import monotonic, perf_counter
from types import TracebackType
from typing import (
Any,
AsyncContextManager,
AsyncIterator,
Awaitable,
Callable,
ClassVar,
ContextManager,
Coroutine,
Dict,
Generator,
Iterable,
List,
Mapping,
Expand All @@ -33,25 +30,36 @@

from .timers import Timer
from .types import DiagT, ServiceT
from .utils.contexts import AsyncExitStack, ExitStack
from .utils.cron import secs_for_next
from .utils.locks import Event
from .utils.logging import CompositeLogger, get_logger, level_number
from .utils.objects import iter_mro_reversed, qualname
from .utils.text import maybecat
from .utils.times import Seconds, want_seconds
from .utils.tracebacks import format_task_stack
from .utils.trees import Node
from .utils.types.trees import NodeT
from .utils.typing import AsyncContextManager

__all__ = ["ServiceBase", "Service", "Diag", "task", "timer", "crontab"]
__all__ = [
"ServiceBase",
"Service",
"Diag",
"task",
"timer",
]

ClockArg = Callable[[], float]

#: Future type: Different types of awaitables.
FutureT = Union[asyncio.Future, Coroutine[Any, None, Any], Awaitable]
FutureT = Union[asyncio.Future, Generator[Any, None, Any], Awaitable]

#: Argument type for ``Service.wait(*events)``
#: Wait can take any number of futures or events to wait for.
WaitArgT = Union[FutureT, Event]
WaitArgT = Union[FutureT, asyncio.Event, Event]

EVENT_TYPES = (asyncio.Event, Event)


class WaitResults(NamedTuple):
Expand Down Expand Up @@ -88,10 +96,10 @@ class ServiceBase(ServiceT):
# the None to logger.
logger: logging.Logger = cast(logging.Logger, None)

def __init_subclass__(cls) -> None:
if cls.abstract:
cls.abstract = False
cls._init_subclass_logger()
def __init_subclass__(self) -> None:
if self.abstract:
self.abstract = False
self._init_subclass_logger()

@classmethod
def _init_subclass_logger(cls) -> None:
Expand Down Expand Up @@ -138,11 +146,11 @@ def _repr_name(self) -> str:
@property
def loop(self) -> asyncio.AbstractEventLoop:
if self._loop is None:
self._loop = asyncio.get_event_loop_policy().get_event_loop()
self._loop = asyncio.get_event_loop()
return self._loop

@loop.setter
def loop(self, loop: asyncio.AbstractEventLoop) -> None:
def loop(self, loop: Optional[asyncio.AbstractEventLoop]) -> None:
self._loop = loop


Expand Down Expand Up @@ -223,7 +231,7 @@ class ServiceCallbacks:
When calling ``await service.start()`` this happens:
.. code-block:: text
.. sourcecode:: text
+--------------------+
| INIT (not started) |
Expand All @@ -247,7 +255,7 @@ class ServiceCallbacks:
When stopping and ``wait_for_shutdown`` is unset, this happens:
.. code-block:: text
.. sourcecode:: text
.-----------------------.
/ await service.stop() |
Expand All @@ -264,7 +272,7 @@ class ServiceCallbacks:
When stopping and ``wait_for_shutdown`` is set, the stop operation
will wait for something to set the shutdown flag ``self.set_shutdown()``:
.. code-block:: text
.. sourcecode:: text
.-----------------------.
/ await service.stop() |
Expand All @@ -285,7 +293,7 @@ class ServiceCallbacks:
When restarting the order is as follows (assuming
``wait_for_shutdown`` unset):
.. code-block:: text
.. sourcecode:: text
.-------------------------.
/ await service.restart() |
Expand Down Expand Up @@ -503,13 +511,13 @@ async def _and_transition(self: ServiceT, *args: Any, **kwargs: Any) -> Any:

return _decorate

def __init_subclass__(cls) -> None:
def __init_subclass__(self) -> None:
# Every new subclass adds @Service.task decorated methods
# to the class-local `_tasks` list.
if cls.abstract:
cls.abstract = False
cls._init_subclass_logger()
cls._init_subclass_tasks()
if self.abstract:
self.abstract = False
self._init_subclass_logger()
self._init_subclass_tasks()

@classmethod
def _init_subclass_tasks(cls) -> None:
Expand Down Expand Up @@ -632,7 +640,7 @@ def add_future(self, coro: Awaitable) -> asyncio.Future:
"""
fut = asyncio.ensure_future(self._execute_task(coro), loop=self.loop)
try:
fut.set_name(repr(coro))
fut.set_name(repr(coro)) # type: ignore
except AttributeError:
pass
fut.__wrapped__ = coro # type: ignore
Expand Down Expand Up @@ -690,7 +698,9 @@ async def join_services(self, services: Sequence[ServiceT]) -> None:
for service in reversed(services):
await service.stop()

async def sleep(self, n: Seconds) -> None:
async def sleep(
self, n: Seconds, *, loop: asyncio.AbstractEventLoop = None
) -> None:
"""Sleep for ``n`` seconds, or until service stopped."""
try:
await asyncio.wait_for(
Expand Down Expand Up @@ -739,7 +749,7 @@ async def wait_first(

futures = {
coro: asyncio.ensure_future(
coro if isinstance(coro, Awaitable) else coro.wait(),
(coro.wait() if isinstance(coro, EVENT_TYPES) else coro),
loop=loop,
)
for coro in coros
Expand Down

0 comments on commit 030d69f

Please sign in to comment.