Title: Theory / Unimportant / CS / Programming / Python / Async / Loop
Tags: constant automatedNewLineAfterCommaSpace
On every note of this deck, unless a note says otherwise:
Page: https://docs.python.org/3.10/library/asyncio-policy.html

Name: event loop
Definition: run asynchronous tasks and callbacks, perform network IO operations, and run subprocesses.
Page: https://docs.python.org/3.10/library/asyncio-eventloop.html
Context: python
Intuition: core of every asyncio application

Instruction: asyncio.get_running_loop()
Page: https://docs.python.org/3.10/library/asyncio-eventloop.html
Effect: the running event loop in the current OS thread.
Language: python
Exception: If there is no running event loop a RuntimeError is raised.

Instruction: asyncio.get_event_loop()
Page: https://docs.python.org/3.10/library/asyncio-eventloop.html
Effect: Create an event loop if none exists currently
Language: python
Returns: the current event loop.

Instruction: asyncio.set_event_loop(loop)
Page: https://docs.python.org/3.10/library/asyncio-eventloop.html
Effect: Set loop as a current event loop for the current OS thread.
Language: python

Instruction: asyncio.new_event_loop()
Page: https://docs.python.org/3.10/library/asyncio-eventloop.html
Language: python
Returns: A new event loop object

Name: Event loop policy
Definition: a global per-process object that controls the management of the event loop.
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Context: python

Question: Which is the context of the default policy
Answer: the current thread
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Context: python, event loop
Name: Event loop policy

Typ: AbstractEventLoopPolicy
Meaning: An event loop policy
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Language: Python

Instruction: asyncio.set_event_loop_policy(policy)
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Effect: Set the current process-wide policy to policy.
Typ: AbstractEventLoopPolicy

Instruction: asyncio.set_event_loop_policy(None)
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Effect: restore default policy
Typ: AbstractEventLoopPolicy

Instruction: event_loop_policy.get_event_loop()
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Effect: the event loop for the current context.
Variables: event_loop_policy: asyncio.AbstractEventLoopPolicy
Typ: AbstractEventLoopPolicy

Instruction: event_loop_policy.set_event_loop(loop)
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Effect: Set the event loop for the current context to loop.
Variables: event_loop_policy: asyncio.AbstractEventLoopPolicy
Typ: AbstractEventLoopPolicy

Instruction: event_loop_policy.new_event_loop()
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Returns: A new event loop object
Variables: event_loop_policy: asyncio.AbstractEventLoopPolicy
Typ: AbstractEventLoopPolicy

Instruction: event_loop_policy.get_child_watcher()
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Returns: a child process watcher object.
Variables: event_loop_policy: asyncio.AbstractEventLoopPolicy
Typ: AbstractChildWatcher

Instruction: event_loop_policy.set_child_watcher(watcher)
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Effect: Set the current child process watcher to watcher.
Variables: event_loop_policy: asyncio.AbstractEventLoopPolicy
Assuming: unix only

Constant: asyncio.DefaultEventLoopPolicy
Meaning: The default asyncio policy. Uses SelectorEventLoop on Unix and ProactorEventLoop on Windows.
Page: https://docs.python.org/3.10/library/asyncio-policy.html

Constant: asyncio.WindowsSelectorEventLoopPolicy
Meaning: event loop policy that uses the SelectorEventLoop event loop implementation.
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Assuming: windows

Constant: asyncio.WindowsProactorEventLoopPolicy
Meaning: event loop policy that uses the ProactorEventLoop event loop implementation.
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Assuming: windows

Typ: AbstractChildWatcher
Meaning: allows customization of how an event loop monitors child processes on Unix.
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Name: A process watcher
Language: Python

Typ: ThreadedChildWatcher
Meaning: Child watcher that starts a new waiting thread for every subprocess spawn.
Language: Python
Name: A process watcher
Extra: It works reliably even when the asyncio event loop is run in a non-main OS thread.
There is no noticeable overhead when handling a big number of children (O(1) each time a child terminates), but starting a thread per process requires extra memory.

Typ: asyncio.MultiLoopChildWatcher
Meaning: registers a SIGCHLD signal handler on instantiation.
The watcher avoids disrupting other code spawning processes by polling every process explicitly on a SIGCHLD signal.
Language: Python
Extra: That can break third-party code that installs a custom handler for SIGCHLD signal.
There is no limitation for running subprocesses from different threads once the watcher is installed.
The solution is safe but it has a significant overhead when handling a big number of processes (O(n) each time a SIGCHLD is received).

Typ: asyncio.SafeChildWatcher
Meaning: uses active event loop from the main thread to handle SIGCHLD signal. If the main thread has no running event loop another thread cannot spawn a subprocess (RuntimeError is raised).
Language: Python
Context: Process watcher

Typ: asyncio.FastChildWatcher
Meaning: This implementation reaps every terminated processes by calling os.waitpid(-1) directly, possibly breaking other code spawning processes and waiting for their termination.
Language: Python
Context: Process watcher
Extra: There is no noticeable overhead when handling a big number of children (O(1) each time a child terminates).
This solution requires a running event loop in the main thread to work, as SafeChildWatcher.

Typ: asyncio.PidfdtChildWatcher
Meaning: This implementation polls process file descriptors (pidfds) to await child process termination.
Language: Python
Context: Process watcher
Extra: In some respects, PidfdChildWatcher is a “Goldilocks” child watcher implementation. It doesn’t require signals or threads, doesn’t interfere with any processes launched outside the event loop, and scales linearly with the number of subprocesses launched by the event loop. The main disadvantage is that pidfds are specific to Linux, and only work on recent (5.3+) kernels.

Question: How to create a process watcher?
Answer: Subclass DefaultEventLoopPolicy and override the methods for which custom behavior is wanted
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Context: Python

Question: What is the default process watcher?
Answer: asyncio.ThreadedChildWatcher
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Context: Python

Instruction: child_watcher.add_child_handler(
  pid,
  callback,
  *args
)
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Effect: Arrange for callback(pid, returncode, *args) to be called when a process with PID equal to pid terminates.
Context: Python
Variables: child_watcher: AbstractChildWatcher
Extra: Specifying another callback for the same process replaces the previous handler.
Assuming: The callback callable must be thread-safe.

Instruction: child_watcher.remove_child_handler(pid)
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Effect: Removes the handler for process with PID equal to pid.
Context: Python
Returns: whether removal was succesful
Variables: child_watcher: AbstractChildWatcher

Instruction: child_watcher.attach_loop(loop)
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Effect: Attach the watcher to an event loop. Detach previous loop if one was attached
Context: Python
Variables: child_watcher: AbstractChildWatcher

Instruction: child_watcher.is_active()
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Context: Python
Returns: Whether watcher is ready to use
Variables: child_watcher: AbstractChildWatcher

Instruction: child_watcher.close()
Page: https://docs.python.org/3.10/library/asyncio-policy.html
Effect: Close the watcher.
Context: Python
Variables: child_watcher: AbstractChildWatcher