Skip to content

Commit

Permalink
docs: Update for the fork and server modules
Browse files Browse the repository at this point in the history
  • Loading branch information
achimnol committed Jan 11, 2021
1 parent f735b70 commit a2932f4
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 20 deletions.
14 changes: 14 additions & 0 deletions docs/aiotools.fork.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Async Fork
==========

.. automodule:: aiotools.fork

.. currentmodule:: aiotools.fork

.. autoclass:: aiotools.fork.AbstractChildProcess

.. autofunction:: aiotools.fork.PosixChildProcess

.. autofunction:: aiotools.fork.PidfdChildProcess

.. autofunction:: aiotools.fork.afork
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ aiotools Documentation

aiotools.context
aiotools.defer
aiotools.fork
aiotools.func
aiotools.iter
aiotools.server
Expand Down
18 changes: 18 additions & 0 deletions src/aiotools/fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
This module implements a simple :func:`os.fork()`-like interface,
but in an asynchronous way with full support for PID file descriptors
on Python 3.9 or higher and the Linux kernel 5.4 or higher.
It internally synchronizes the beginning and readiness status of child processes
so that the users may assume that the child process is completely interruptible after
:func:`afork()` returns.
"""

import asyncio
Expand Down Expand Up @@ -50,6 +54,9 @@


class AbstractChildProcess(metaclass=ABCMeta):
"""
The abstract interface to control and monitor a forked child process.
"""

@abstractmethod
def send_signal(self, signum: int) -> None:
Expand All @@ -61,6 +68,9 @@ async def wait(self) -> int:


class PosixChildProcess(AbstractChildProcess):
"""
A POSIX-compatible version of :class:`AbstractChildProcess`.
"""

def __init__(self, pid: int) -> None:
self._pid = pid
Expand Down Expand Up @@ -102,6 +112,9 @@ async def wait(self) -> int:


class PidfdChildProcess(AbstractChildProcess):
"""
A PID file descriptor-based version of :class:`AbstractChildProcess`.
"""

def __init__(self, pid: int, pidfd: int) -> None:
self._pid = pid
Expand Down Expand Up @@ -238,6 +251,11 @@ async def _clone_pidfd(child_func: Callable[[], int]) -> Tuple[int, int]:


async def afork(child_func: Callable[[], int]) -> AbstractChildProcess:
"""
Fork the current process and execute the given function in the child.
The return value of the function will become the exit code of the child
process.
"""
if _has_pidfd:
pid, pidfd = await _clone_pidfd(child_func)
return PidfdChildProcess(pid, pidfd)
Expand Down
29 changes: 9 additions & 20 deletions src/aiotools/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,27 +416,11 @@ def start_server(
extra_procs: An iterable of functions that consist of extra processes
whose lifecycles are synchronized with other workers.
You should write the shutdown steps of them differently
depending on the value of **use_threading** argument.
If it is ``False`` (default), they will get
a :class:`BaseException` depending on the received stop signal
number, either :class:`KeyboardInterrupt` (for SIGINT),
:class:`SystemExit` (for SIGTERM), or
:class:`InterruptedBySignal` (otherwise).
If it is ``True``, they should check their **intr_event**
argument periodically because there is no way to install
signal handlers in Python threads (only the main thread
can install signal handlers).
They should set up their own signal handlers.
It should accept the following three arguments:
* **intr_event**: :class:`threading.Event` object that
signals the interruption of the main thread (only
available when **use_threading** is ``True``; otherwise
it is set to ``None``)
* **intr_event**: Always ``None``, kept for legacy
* **pidx**: same to **worker_actxmgr** argument
* **args**: same to **worker_actxmgr** argument
Expand Down Expand Up @@ -490,11 +474,16 @@ def start_server(
**start_method** argument can be set to change the subprocess spawning
implementation.
.. versionchanged:: 1.2.0
.. deprecated:: 1.2.0
Deprecated **start_method** and **use_threading**, in favor of our new
The **start_method** and **use_threading** arguments, in favor of our new
:func:`afork()` function which provides better synchronization and pid-fd
support.
.. versionchanged:: 1.2.0
The **extra_procs** will be always separate processes since **use_threading**
is deprecated and thus **intr_event** arguments are now always ``None``.
"""

@_main_ctxmgr
Expand Down

0 comments on commit a2932f4

Please sign in to comment.