mode
¶
AsyncIO Service-based programming.
- class mode.BaseSignal(*, name: Optional[str] = None, owner: Optional[Type] = None, loop: Optional[AbstractEventLoop] = None, default_sender: Optional[Any] = None, receivers: Optional[MutableSet[Union[Callable[[], Union[Callable[[T, Any, BaseSignalT, Any], None], Callable[[T, Any, BaseSignalT, Any], Awaitable[None]]]], weakref[Union[Callable[[T, Any, mode.types.signals.BaseSignalT, Any], NoneType], Callable[[T, Any, mode.types.signals.BaseSignalT, Any], Awaitable[NoneType]]]]]]] = None, filter_receivers: Optional[MutableMapping[Any, MutableSet[Union[Callable[[], Union[Callable[[T, Any, BaseSignalT, Any], None], Callable[[T, Any, BaseSignalT, Any], Awaitable[None]]]], weakref[Union[Callable[[T, Any, mode.types.signals.BaseSignalT, Any], NoneType], Callable[[T, Any, mode.types.signals.BaseSignalT, Any], Awaitable[NoneType]]]]]]]] = None)¶
Base class for signal/observer pattern.
- asdict() Mapping[str, Any] ¶
- clone(**kwargs: Any) BaseSignalT ¶
- connect(fun: Optional[Union[Callable[[T, Any, BaseSignalT, Any], None], Callable[[T, Any, BaseSignalT, Any], Awaitable[None]]]] = None, **kwargs: Any) Callable ¶
- disconnect(fun: Union[Callable[[T, Any, BaseSignalT, Any], None], Callable[[T, Any, BaseSignalT, Any], Awaitable[None]]], *, weak: bool = False, sender: Optional[Any] = None) None ¶
- property ident: str¶
- iter_receivers(sender: T_contra) Iterable[Union[Callable[[T, Any, BaseSignalT, Any], None], Callable[[T, Any, BaseSignalT, Any], Awaitable[None]]]] ¶
- property label: str¶
- unpack_sender_from_args(*args: Any) tuple[T, tuple[Any, ...]] ¶
- with_default_sender(sender: Optional[Any] = None) BaseSignalT ¶
- class mode.BaseSignalT(*, name: Optional[str] = None, owner: Optional[Type] = None, loop: Optional[AbstractEventLoop] = None, default_sender: Optional[Any] = None, receivers: Optional[MutableSet[Union[Callable[[], Union[Callable[[T, Any, BaseSignalT, Any], None], Callable[[T, Any, BaseSignalT, Any], Awaitable[None]]]], weakref[Union[Callable[[T, Any, mode.types.signals.BaseSignalT, Any], NoneType], Callable[[T, Any, mode.types.signals.BaseSignalT, Any], Awaitable[NoneType]]]]]]] = None, filter_receivers: Optional[MutableMapping[Any, MutableSet[Union[Callable[[], Union[Callable[[T, Any, BaseSignalT, Any], None], Callable[[T, Any, BaseSignalT, Any], Awaitable[None]]]], weakref[Union[Callable[[T, Any, mode.types.signals.BaseSignalT, Any], NoneType], Callable[[T, Any, mode.types.signals.BaseSignalT, Any], Awaitable[NoneType]]]]]]]] = None)¶
Base type for all signals.
- abstract clone(**kwargs: Any) BaseSignalT ¶
- abstract connect(fun: Union[Callable[[T, Any, BaseSignalT, Any], None], Callable[[T, Any, BaseSignalT, Any], Awaitable[None]]], **kwargs: Any) Callable ¶
- abstract disconnect(fun: Union[Callable[[T, Any, BaseSignalT, Any], None], Callable[[T, Any, BaseSignalT, Any], Awaitable[None]]], *, sender: Optional[Any] = None, weak: bool = True) None ¶
- name: str¶
- owner: Optional[Type]¶
- abstract with_default_sender(sender: Optional[Any] = None) BaseSignalT ¶
- class mode.CrashingSupervisor(*services: ~mode.types.services.ServiceT, max_restarts: ~typing.Union[~datetime.timedelta, int, float, str] = 100.0, over: ~typing.Union[~datetime.timedelta, int, float, str] = 1.0, raises: ~typing.Type[BaseException] = <class 'mode.exceptions.MaxRestartsExceeded'>, replacement: ~typing.Optional[~typing.Callable[[~mode.types.services.ServiceT, int], ~typing.Awaitable[~mode.types.services.ServiceT]]] = None, **kwargs: ~typing.Any)¶
Supervisor that crashes the whole program.
- logger: logging.Logger = <Logger mode.supervisors (WARNING)>¶
- wakeup() None ¶
- class mode.ForfeitOneForAllSupervisor(*services: ~mode.types.services.ServiceT, max_restarts: ~typing.Union[~datetime.timedelta, int, float, str] = 100.0, over: ~typing.Union[~datetime.timedelta, int, float, str] = 1.0, raises: ~typing.Type[BaseException] = <class 'mode.exceptions.MaxRestartsExceeded'>, replacement: ~typing.Optional[~typing.Callable[[~mode.types.services.ServiceT, int], ~typing.Awaitable[~mode.types.services.ServiceT]]] = None, **kwargs: ~typing.Any)¶
If one service in the group crashes, we give up on all of them.
- logger: logging.Logger = <Logger mode.supervisors (WARNING)>¶
- async restart_services(services: list[mode.types.services.ServiceT]) None ¶
- class mode.ForfeitOneForOneSupervisor(*services: ~mode.types.services.ServiceT, max_restarts: ~typing.Union[~datetime.timedelta, int, float, str] = 100.0, over: ~typing.Union[~datetime.timedelta, int, float, str] = 1.0, raises: ~typing.Type[BaseException] = <class 'mode.exceptions.MaxRestartsExceeded'>, replacement: ~typing.Optional[~typing.Callable[[~mode.types.services.ServiceT, int], ~typing.Awaitable[~mode.types.services.ServiceT]]] = None, **kwargs: ~typing.Any)¶
Supervisor that if a service crashes, we do not restart it.
- logger: logging.Logger = <Logger mode.supervisors (WARNING)>¶
- async restart_services(services: list[mode.types.services.ServiceT]) None ¶
- class mode.OneForAllSupervisor(*services: ~mode.types.services.ServiceT, max_restarts: ~typing.Union[~datetime.timedelta, int, float, str] = 100.0, over: ~typing.Union[~datetime.timedelta, int, float, str] = 1.0, raises: ~typing.Type[BaseException] = <class 'mode.exceptions.MaxRestartsExceeded'>, replacement: ~typing.Optional[~typing.Callable[[~mode.types.services.ServiceT, int], ~typing.Awaitable[~mode.types.services.ServiceT]]] = None, **kwargs: ~typing.Any)¶
Supervisor that restarts all services when a service crashes.
- logger: logging.Logger = <Logger mode.supervisors (WARNING)>¶
- async restart_services(services: list[mode.types.services.ServiceT]) None ¶
- class mode.OneForOneSupervisor(*services: ~mode.types.services.ServiceT, max_restarts: ~typing.Union[~datetime.timedelta, int, float, str] = 100.0, over: ~typing.Union[~datetime.timedelta, int, float, str] = 1.0, raises: ~typing.Type[BaseException] = <class 'mode.exceptions.MaxRestartsExceeded'>, replacement: ~typing.Optional[~typing.Callable[[~mode.types.services.ServiceT, int], ~typing.Awaitable[~mode.types.services.ServiceT]]] = None, **kwargs: ~typing.Any)¶
Supervisor simply restarts any crashed service.
- logger: logging.Logger = <Logger mode.supervisors (WARNING)>¶
- class mode.Service(*, beacon: Optional[NodeT] = None, loop: Optional[AbstractEventLoop] = None)¶
An asyncio service that can be started/stopped/restarted.
- Keyword Arguments:
beacon (NodeT) – Beacon used to track services in a graph.
loop (AbstractEventLoop) – Event loop object.
- class Diag(service: ServiceT)¶
Service diagnostics.
This can be used to track what your service is doing. For example if your service is a Kafka consumer with a background thread that commits the offset every 30 seconds, you may want to see when this happens:
DIAG_COMMITTING = 'committing' class Consumer(Service): @Service.task async def _background_commit(self) -> None: while not self.should_stop: await self.sleep(30.0) self.diag.set_flag(DIAG_COMITTING) try: await self._consumer.commit() finally: self.diag.unset_flag(DIAG_COMMITTING)
The above code is setting the flag manually, but you can also use a decorator to accomplish the same thing:
@Service.timer(30.0) async def _background_commit(self) -> None: await self.commit() @Service.transitions_with(DIAG_COMITTING) async def commit(self) -> None: await self._consumer.commit()
- set_flag(flag: str) None ¶
- unset_flag(flag: str) None ¶
- abstract: ClassVar[bool] = False¶
Set to True if this service class is abstract-only, meaning it will only be used as a base class.
- async add_async_context(context: AsyncContextManager) Any ¶
- add_context(context: ContextManager) Any ¶
- add_dependency(service: ServiceT) ServiceT ¶
Add dependency to other service.
The service will be started/stopped with this service.
- add_future(coro: Awaitable) Future ¶
Add relationship to asyncio.Future.
The future will be joined when this service is stopped.
- async crash(reason: BaseException) None ¶
Crash the service and all child services.
- property crash_reason: Optional[BaseException]¶
- property crashed: bool¶
- classmethod crontab(cron_format: str, *, timezone: Optional[tzinfo] = None) Callable[[Callable], ServiceTask] ¶
Background timer executing periodic task based on Crontab description.
Example
>>> class S(Service): ... ... @Service.crontab(cron_format='30 18 * * *', timezone=pytz.timezone('US/Pacific')) ... async def every_6_30_pm_pacific(self): ... print('IT IS 6:30pm') ... ... @Service.crontab(cron_format='30 18 * * *') ... async def every_6_30_pm(self): ... print('6:30pm UTC')
- classmethod from_awaitable(coro: Awaitable, *, name: Optional[str] = None, **kwargs: Any) ServiceT ¶
- human_tracebacks() str ¶
- async itertimer(interval: ~typing.Union[~datetime.timedelta, int, float, str], *, max_drift_correction: float = 0.1, sleep: ~typing.Optional[~typing.Callable[[...], ~typing.Awaitable]] = None, clock: ~typing.Callable[[], float] = <built-in function perf_counter>, name: str = '') AsyncIterator[float] ¶
Sleep
interval
seconds for every iteration.This is an async iterator that takes advantage of
Timer()
to monitor drift and timer oerlap.Uses
Service.sleep
so exits fast when the service is stopped.Note
Will sleep the full interval seconds before returning from first iteration.
Examples
>>> async for sleep_time in self.itertimer(1.0): ... print('another second passed, just woke up...') ... await perform_some_http_request()
- property label: str¶
Label used for graphs.
- logger: logging.Logger = <Logger mode.services (WARNING)>¶
- async maybe_start() bool ¶
Start the service, if it has not already been started.
- mundane_level = 'info'¶
The log level for mundane info such as starting, stopping, etc. Set this to
"debug"
for less information.
- async restart() None ¶
Restart this service.
- restart_count: int = 0¶
Current number of times this service instance has been restarted.
- service_reset() None ¶
- set_shutdown() None ¶
Set the shutdown signal.
Notes
If
wait_for_shutdown
is set, stopping the service will wait for this flag to be set.
- property shortlabel: str¶
Label used for logging.
- property should_stop: bool¶
Return
True
if the service must stop.
- shutdown_timeout: float = 60.0¶
Time to wait for shutdown flag set before we give up.
- async sleep(n: Union[timedelta, int, float, str]) None ¶
Sleep for
n
seconds, or until service stopped.
- async start() None ¶
- property started: bool¶
Return
True
if the service was started.
- property state: str¶
Service state - as a human readable string.
- async stop() None ¶
Stop the service.
- classmethod task(fun: Callable[[Any], Awaitable[None]]) ServiceTask ¶
Decorate function to be used as background task.
Example
>>> class S(Service): ... ... @Service.task ... async def background_task(self): ... while not self.should_stop: ... await self.sleep(1.0) ... print('Waking up')
- classmethod timer(interval: Union[timedelta, int, float, str], *, exec_first: bool = False, name: Optional[str] = None, max_drift_correction: float = 0.1) Callable[[Callable], ServiceTask] ¶
Background timer executing every
n
seconds.Example
>>> class S(Service): ... ... @Service.timer(1.0) ... async def background_timer(self): ... print('Waking up')
- tracebacks() Mapping[str, str] ¶
- async transition_with(flag: str, fut: Awaitable, *args: Any, **kwargs: Any) Any ¶
- classmethod transitions_to(flag: str) Callable ¶
Decorate function to set and reset diagnostic flag.
- async wait(*coros: Union[Future, Generator[Any, None, Any], Awaitable, Event], timeout: Optional[Union[timedelta, int, float, str]] = None) WaitResult ¶
Wait for coroutines to complete, or until the service stops.
- async wait_first(*coros: Union[Future, Generator[Any, None, Any], Awaitable, Event], timeout: Optional[Union[timedelta, int, float, str]] = None) WaitResults ¶
- wait_for_shutdown: bool = False¶
Set to True if .stop must wait for the shutdown flag to be set.
- async wait_for_stopped(*coros: Union[Future, Generator[Any, None, Any], Awaitable, Event], timeout: Optional[Union[timedelta, int, float, str]] = None) bool ¶
- async wait_many(coros: Iterable[Union[Future, Generator[Any, None, Any], Awaitable, Event]], *, timeout: Optional[Union[timedelta, int, float, str]] = None) WaitResult ¶
- async wait_until_stopped() None ¶
Wait until the service is signalled to stop.
- class mode.ServiceT(*, beacon: Optional[NodeT] = None, loop: Optional[AbstractEventLoop] = None)¶
Abstract type for an asynchronous service that can be started/stopped.
See also
- abstract async add_async_context(context: AsyncContextManager) Any ¶
- abstract add_context(context: ContextManager) Any ¶
- async_exit_stack: AsyncExitStack¶
- abstract async crash(reason: BaseException) None ¶
- abstract property crash_reason: Optional[BaseException]¶
- abstract property crashed: bool¶
- exit_stack: ExitStack¶
- abstract property label: str¶
- abstract property loop: AbstractEventLoop¶
- abstract async maybe_start() bool ¶
- abstract async restart() None ¶
- restart_count: int = 0¶
- abstract service_reset() None ¶
- abstract set_shutdown() None ¶
- abstract property shortlabel: str¶
- abstract property should_stop: bool¶
- shutdown_timeout: float¶
- abstract async start() None ¶
- abstract property started: bool¶
- abstract property state: str¶
- abstract async stop() None ¶
- supervisor: Optional[SupervisorStrategyT] = None¶
- wait_for_shutdown: bool = False¶
- abstract async wait_until_stopped() None ¶
- class mode.Signal(*, name: Optional[str] = None, owner: Optional[Type] = None, loop: Optional[AbstractEventLoop] = None, default_sender: Optional[Any] = None, receivers: Optional[MutableSet[Union[Callable[[], Union[Callable[[T, Any, BaseSignalT, Any], None], Callable[[T, Any, BaseSignalT, Any], Awaitable[None]]]], weakref[Union[Callable[[T, Any, mode.types.signals.BaseSignalT, Any], NoneType], Callable[[T, Any, mode.types.signals.BaseSignalT, Any], Awaitable[NoneType]]]]]]] = None, filter_receivers: Optional[MutableMapping[Any, MutableSet[Union[Callable[[], Union[Callable[[T, Any, BaseSignalT, Any], None], Callable[[T, Any, BaseSignalT, Any], Awaitable[None]]]], weakref[Union[Callable[[T, Any, mode.types.signals.BaseSignalT, Any], NoneType], Callable[[T, Any, mode.types.signals.BaseSignalT, Any], Awaitable[NoneType]]]]]]]] = None)¶
Asynchronous signal (using
async def
functions).- async send(*args: Any, **kwargs: Any) None ¶
- class mode.SignalT(*, name: Optional[str] = None, owner: Optional[Type] = None, loop: Optional[AbstractEventLoop] = None, default_sender: Optional[Any] = None, receivers: Optional[MutableSet[Union[Callable[[], Union[Callable[[T, Any, BaseSignalT, Any], None], Callable[[T, Any, BaseSignalT, Any], Awaitable[None]]]], weakref[Union[Callable[[T, Any, mode.types.signals.BaseSignalT, Any], NoneType], Callable[[T, Any, mode.types.signals.BaseSignalT, Any], Awaitable[NoneType]]]]]]] = None, filter_receivers: Optional[MutableMapping[Any, MutableSet[Union[Callable[[], Union[Callable[[T, Any, BaseSignalT, Any], None], Callable[[T, Any, BaseSignalT, Any], Awaitable[None]]]], weakref[Union[Callable[[T, Any, mode.types.signals.BaseSignalT, Any], NoneType], Callable[[T, Any, mode.types.signals.BaseSignalT, Any], Awaitable[NoneType]]]]]]]] = None)¶
Base class for all async signals (using
async def
).- abstract async send(sender: T_contra, *args: Any, **kwargs: Any) None ¶
- class mode.SupervisorStrategy(*services: ~mode.types.services.ServiceT, max_restarts: ~typing.Union[~datetime.timedelta, int, float, str] = 100.0, over: ~typing.Union[~datetime.timedelta, int, float, str] = 1.0, raises: ~typing.Type[BaseException] = <class 'mode.exceptions.MaxRestartsExceeded'>, replacement: ~typing.Optional[~typing.Callable[[~mode.types.services.ServiceT, int], ~typing.Awaitable[~mode.types.services.ServiceT]]] = None, **kwargs: ~typing.Any)¶
Base class for all supervisor strategies.
- property label: str¶
Label used for graphs.
- logger: logging.Logger = <Logger mode.supervisors (WARNING)>¶
- async on_start() None ¶
Service is starting.
- async on_stop() None ¶
Service is being stopped/restarted.
- async restart_services(services: list[mode.types.services.ServiceT]) None ¶
- async run_until_complete() None ¶
- async start_services(services: list[mode.types.services.ServiceT]) None ¶
- async stop_services(services: list[mode.types.services.ServiceT]) None ¶
- wakeup() None ¶
- class mode.SupervisorStrategyT(*services: ServiceT, max_restarts: Union[timedelta, int, float, str] = 100.0, over: Union[timedelta, int, float, str] = 1.0, raises: Optional[Type[BaseException]] = None, replacement: Optional[Callable[[ServiceT, int], Awaitable[ServiceT]]] = None, **kwargs: Any)¶
Base type for all supervisor strategies.
- max_restarts: float¶
- over: float¶
- raises: Type[BaseException]¶
- abstract wakeup() None ¶
- class mode.SyncSignal(*, name: Optional[str] = None, owner: Optional[Type] = None, loop: Optional[AbstractEventLoop] = None, default_sender: Optional[Any] = None, receivers: Optional[MutableSet[Union[Callable[[], Union[Callable[[T, Any, BaseSignalT, Any], None], Callable[[T, Any, BaseSignalT, Any], Awaitable[None]]]], weakref[Union[Callable[[T, Any, mode.types.signals.BaseSignalT, Any], NoneType], Callable[[T, Any, mode.types.signals.BaseSignalT, Any], Awaitable[NoneType]]]]]]] = None, filter_receivers: Optional[MutableMapping[Any, MutableSet[Union[Callable[[], Union[Callable[[T, Any, BaseSignalT, Any], None], Callable[[T, Any, BaseSignalT, Any], Awaitable[None]]]], weakref[Union[Callable[[T, Any, mode.types.signals.BaseSignalT, Any], NoneType], Callable[[T, Any, mode.types.signals.BaseSignalT, Any], Awaitable[NoneType]]]]]]]] = None)¶
Signal that is synchronous (using regular
def
functions).- clone(**kwargs: Any) SyncSignalT ¶
- send(*args: Any, **kwargs: Any) None ¶
- with_default_sender(sender: Any = None) SyncSignalT ¶
- class mode.SyncSignalT(*, name: Optional[str] = None, owner: Optional[Type] = None, loop: Optional[AbstractEventLoop] = None, default_sender: Optional[Any] = None, receivers: Optional[MutableSet[Union[Callable[[], Union[Callable[[T, Any, BaseSignalT, Any], None], Callable[[T, Any, BaseSignalT, Any], Awaitable[None]]]], weakref[Union[Callable[[T, Any, mode.types.signals.BaseSignalT, Any], NoneType], Callable[[T, Any, mode.types.signals.BaseSignalT, Any], Awaitable[NoneType]]]]]]] = None, filter_receivers: Optional[MutableMapping[Any, MutableSet[Union[Callable[[], Union[Callable[[T, Any, BaseSignalT, Any], None], Callable[[T, Any, BaseSignalT, Any], Awaitable[None]]]], weakref[Union[Callable[[T, Any, mode.types.signals.BaseSignalT, Any], NoneType], Callable[[T, Any, mode.types.signals.BaseSignalT, Any], Awaitable[NoneType]]]]]]]] = None)¶
Base class for all synchronous signals (using regular
def
).- abstract clone(**kwargs: Any) SyncSignalT ¶
- abstract send(sender: T_contra, *args: Any, **kwargs: Any) None ¶
- abstract with_default_sender(sender: Any = None) SyncSignalT ¶
- class mode.Worker(*services: ServiceT, debug: bool = False, quiet: bool = False, log_level: Severity = 20, log_file: str | os.PathLike | IO | None = None, log_handlers: Iterable[Handler] | None = None, redirect_stdouts: bool = True, redirect_stdouts_level: Severity = 30, stdout: IO | None = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, stderr: IO | None = <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>, override_logging: bool = True, logging_config: dict | None = None, console_port: int = 50101, blocking_timeout: Seconds = 10.0, daemon: bool = True, loop: asyncio.AbstractEventLoop | None = None, **kwargs: Any)¶
Start mode service from the command-line.
- BLOCK_DETECTOR: ClassVar[str] = 'mode.debug:BlockingDetector'¶
- property blocking_detector: BlockingDetector¶
- blocking_timeout: Seconds¶
- carp(msg: str) None ¶
Write warning to standard err.
- console_port: int¶
- debug: bool¶
- async default_on_first_start() None ¶
- execute_from_commandline() NoReturn ¶
- install_signal_handlers() None ¶
- log_file: str | os.PathLike | IO | None¶
- log_handlers: list[Handler]¶
- log_level: Severity | None¶
- logger: logging.Logger = <Logger mode.worker (WARNING)>¶
- logging_config: dict | None¶
- async maybe_start_blockdetection() None ¶
- async on_execute() None ¶
- async on_first_start() None ¶
Service started for the first time in this process.
- on_setup_root_logger(logger: Logger, level: int) None ¶
- async on_started() None ¶
Service has started.
- on_worker_shutdown() None ¶
- quiet: bool¶
- redirect_stdouts: bool¶
- redirect_stdouts_level: int¶
- say(msg: str) None ¶
Write message to standard out.
- stderr: IO¶
- stdout: IO¶
- stop_and_shutdown() None ¶
- class mode.flight_recorder(logger: Logger, *, timeout: Union[timedelta, int, float, str], loop: Optional[AbstractEventLoop] = None)¶
Flight Recorder context for use with
with
statement.This is a logging utility to log stuff only when something times out.
For example if you have a background thread that is sometimes hanging:
class RedisCache(mode.Service): @mode.timer(1.0) def _background_refresh(self) -> None: self._users = await self.redis_client.get(USER_KEY) self._posts = await self.redis_client.get(POSTS_KEY)
You want to figure out on what line this is hanging, but logging all the time will provide way too much output, and will even change how fast the program runs and that can mask race conditions, so that they never happen.
Use the flight recorder to save the logs and only log when it times out:
logger = mode.get_logger(__name__) class RedisCache(mode.Service): @mode.timer(1.0) def _background_refresh(self) -> None: with mode.flight_recorder(logger, timeout=10.0) as on_timeout: on_timeout.info(f'+redis_client.get({USER_KEY!r})') await self.redis_client.get(USER_KEY) on_timeout.info(f'-redis_client.get({USER_KEY!r})') on_timeout.info(f'+redis_client.get({POSTS_KEY!r})') await self.redis_client.get(POSTS_KEY) on_timeout.info(f'-redis_client.get({POSTS_KEY!r})')
If the body of this
with
statement completes before the timeout, the logs are forgotten about and never emitted – if it takes more than ten seconds to complete, we will see these messages in the log:[2018-04-19 09:43:55,877: WARNING]: Warning: Task timed out! [2018-04-19 09:43:55,878: WARNING]: Please make sure it is hanging before restarting. [2018-04-19 09:43:55,878: INFO]: [Flight Recorder-1] (started at Thu Apr 19 09:43:45 2018) Replaying logs... [2018-04-19 09:43:55,878: INFO]: [Flight Recorder-1] (Thu Apr 19 09:43:45 2018) +redis_client.get('user') [2018-04-19 09:43:55,878: INFO]: [Flight Recorder-1] (Thu Apr 19 09:43:49 2018) -redis_client.get('user') [2018-04-19 09:43:55,878: INFO]: [Flight Recorder-1] (Thu Apr 19 09:43:46 2018) +redis_client.get('posts') [2018-04-19 09:43:55,878: INFO]: [Flight Recorder-1] -End of log-
Now we know this
redis_client.get
call can take too long to complete, and should consider adding a timeout to it.- activate() None ¶
- blush() None ¶
- cancel() None ¶
- enabled_by: _asyncio.Task | None¶
- extra_context: dict[str, Any]¶
- flush_logs(ident: Optional[str] = None) None ¶
- log(severity: int, message: str, *args: Any, **kwargs: Any) None ¶
- logger: Logger¶
- loop: AbstractEventLoop¶
- started_at_date: str | None¶
- timeout: float¶
- wrap(severity: int, obj: Any) Logwrapped ¶
- wrap_debug(obj: Any) Logwrapped ¶
- wrap_error(obj: Any) Logwrapped ¶
- wrap_info(obj: Any) Logwrapped ¶
- wrap_warn(obj: Any) Logwrapped ¶
- mode.get_logger(name: str) Logger ¶
Get logger by name.
- mode.label(s: Any) str ¶
Return the name of an object as string.
- mode.setup_logging(*, log_level: Optional[Union[int, str]] = None, log_file: Optional[Union[PathLike, str, IO]] = None, log_handlers: Optional[Iterable[Handler]] = None, logging_config: Optional[dict] = None) int ¶
Configure logging subsystem.
- mode.shortlabel(s: Any) str ¶
Return the shortened name of an object as string.
- mode.task(fun: Callable[[Any], Awaitable[None]]) ServiceTask ¶
Decorate function to be used as background task.
Example
>>> class S(Service): ... ... @Service.task ... async def background_task(self): ... while not self.should_stop: ... await self.sleep(1.0) ... print('Waking up')
- mode.timer(interval: Union[timedelta, int, float, str], *, exec_first: bool = False, name: Optional[str] = None, max_drift_correction: float = 0.1) Callable[[Callable], ServiceTask] ¶
Background timer executing every
n
seconds.Example
>>> class S(Service): ... ... @Service.timer(1.0) ... async def background_timer(self): ... print('Waking up')
- mode.want_seconds(s: int | float | str | datetime.timedelta) float ¶
- mode.want_seconds(s: int | float) float
- mode.want_seconds(s: int | float) float
- mode.want_seconds(s: str) float
- mode.want_seconds(s: timedelta) float
Convert
Seconds
to float.