-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* allow paused tasks, use scheduler timezone instead of tzlocal, make tzlocal optional (#80) Changes: - cleanup unused to_bool - pass timezone info from scheduler to get_next_trigger_time, so they are scheduler specific - make tzlocal optional and fallback to utc - allow to_datetime be used without timezone - allow submitting paused tasks - replace UndefinedType by Undefined and add a shim for backward compatibility - shrink pending_tasks, store_alias is now set in add_task - allow updating task attributes while submitting via add_task - fix incorrect fn references in documentation - update documentation - allow updating more attributes in-place in add_task - remove old types from TaskState - allow submitting tasks only once (set a fuse submitted) - add tests - update release notes * optional loguru, allow switching logging (#81) - make loguru optional, fallback to normal logging - make normal logging selectable by overwriting either per scheduler or per default_loggers_class in asyncz.schedulers.base - splitout process_pool from pool and pass special logger - provide tests - update release notes and docs * fix test workflow and docker-compose * fix python 3.8 typings * bump version * add warning about flaky integration tests * fix spurious integration test failures --------- Co-authored-by: Alexander <[email protected]>
- Loading branch information
Showing
45 changed files
with
850 additions
and
378 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
__version__ = "0.10.1" | ||
__version__ = "0.11.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import concurrent.futures | ||
from multiprocessing import Pipe, connection | ||
from threading import Thread | ||
from typing import TYPE_CHECKING, Any, Optional, cast | ||
|
||
from asyncz.executors.pool import BasePoolExecutor | ||
|
||
if TYPE_CHECKING: | ||
import logging | ||
|
||
from asyncz.schedulers.types import SchedulerType | ||
|
||
# because multiprocessing is heavy weight, it is split out from pool | ||
|
||
|
||
class ProcessPoolLoggerSenderFnWrap: | ||
def __init__(self, send_pipe: connection.Connection, fn_name: str) -> None: | ||
self.send_pipe = send_pipe | ||
self.fn_name = fn_name | ||
|
||
def __call__(self, *args: Any, **kwargs: Any) -> None: | ||
self.send_pipe.send((self.fn_name, args, kwargs)) | ||
|
||
|
||
class ProcessPoolLoggerSender: | ||
def __init__(self, send_pipe: connection.Connection) -> None: | ||
self.send_pipe = send_pipe | ||
|
||
def __getattr__(self, item: str) -> Any: | ||
if item.startswith("_"): | ||
return object.__getattr__(self, item) | ||
return ProcessPoolLoggerSenderFnWrap(self.send_pipe, item) | ||
|
||
|
||
class ProcessPoolReceiver(Thread): | ||
def __init__(self, receive_pipe: connection.Connection, logger: "logging.Logger") -> None: | ||
super().__init__() | ||
self.receive_pipe = receive_pipe | ||
self.logger = logger | ||
self.start() | ||
|
||
def run(self) -> None: | ||
try: | ||
while True: | ||
fn_name, args, kwargs = self.receive_pipe.recv() | ||
if not fn_name.startswith("_"): | ||
getattr(self.logger, fn_name)(*args, **kwargs) | ||
except EOFError: | ||
pass | ||
|
||
|
||
class ProcessPoolExecutor(BasePoolExecutor): | ||
""" | ||
An executor that runs tasks in a concurrent.futures process pool. | ||
Args: | ||
max_workers: The maximum number of spawned processes. | ||
pool_kwargs: Dict of keyword arguments to pass to the underlying | ||
ProcessPoolExecutor constructor. | ||
""" | ||
|
||
def __init__( | ||
self, max_workers: int = 10, pool_kwargs: Optional[Any] = None, **kwargs: Any | ||
) -> None: | ||
self.receive_pipe, self.send_pipe = Pipe(False) | ||
pool_kwargs = pool_kwargs or {} | ||
pool = concurrent.futures.ProcessPoolExecutor(int(max_workers), **pool_kwargs) | ||
super().__init__(pool, **kwargs) | ||
|
||
def start(self, scheduler: "SchedulerType", alias: str) -> None: | ||
super().start(scheduler, alias) | ||
assert self.logger is not None, "logger is None" | ||
# move the old logger to logger_receiver | ||
self.logger_receiver = ProcessPoolReceiver(self.receive_pipe, self.logger) | ||
# and send the process logger instead | ||
self.logger = cast("logging.Logger", ProcessPoolLoggerSender(self.send_pipe)) | ||
|
||
def shutdown(self, wait: bool = True) -> None: | ||
super().shutdown(wait=wait) | ||
self.send_pipe.close() | ||
self.logger_receiver.join() |
Oops, something went wrong.