blob: 6212df85dbc10a980c764a45bc80db96d1850e62 [file] [log] [blame]
Yury Selivanov7c7605f2018-09-11 09:54:40 -07001.. currentmodule:: asyncio
2
3
4.. _asyncio-policies:
5
6========
7Policies
8========
9
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -040010An event loop policy is a global per-process object that controls
11the management of the event loop. Each event loop has a default
12policy, which can be changed and customized using the policy API.
Yury Selivanov7c7605f2018-09-11 09:54:40 -070013
Carol Willing6d9767f2018-09-12 17:09:08 -070014A policy defines the notion of *context* and manages a
Yury Selivanov7c7605f2018-09-11 09:54:40 -070015separate event loop per context. The default policy
Carol Willing6d9767f2018-09-12 17:09:08 -070016defines *context* to be the current thread.
Yury Selivanov7c7605f2018-09-11 09:54:40 -070017
18By using a custom event loop policy, the behavior of
19:func:`get_event_loop`, :func:`set_event_loop`, and
20:func:`new_event_loop` functions can be customized.
21
22Policy objects should implement the APIs defined
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -040023in the :class:`AbstractEventLoopPolicy` abstract base class.
Yury Selivanov7c7605f2018-09-11 09:54:40 -070024
25
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -040026Getting and Setting the Policy
27==============================
Yury Selivanov7c7605f2018-09-11 09:54:40 -070028
29The following functions can be used to get and set the policy
30for the current process:
31
32.. function:: get_event_loop_policy()
33
34 Return the current process-wide policy.
35
36.. function:: set_event_loop_policy(policy)
37
38 Set the current process-wide policy to *policy*.
39
40 If *policy* is set to ``None``, the default policy is restored.
41
42
43Policy Objects
44==============
45
46The abstract event loop policy base class is defined as follows:
47
48.. class:: AbstractEventLoopPolicy
49
50 An abstract base class for asyncio policies.
51
52 .. method:: get_event_loop()
53
54 Get the event loop for the current context.
55
56 Return an event loop object implementing the
57 :class:`AbstractEventLoop` interface.
58
59 This method should never return ``None``.
60
61 .. versionchanged:: 3.6
62
63 .. method:: set_event_loop(loop)
64
65 Set the event loop for the current context to *loop*.
66
67 .. method:: new_event_loop()
68
69 Create and return a new event loop object.
70
71 This method should never return ``None``.
72
73 .. method:: get_child_watcher()
74
75 Get a child process watcher object.
76
77 Return a watcher object implementing the
78 :class:`AbstractChildWatcher` interface.
79
80 This function is Unix specific.
81
82 .. method:: set_child_watcher(watcher)
83
sth1b29c032018-12-30 23:01:28 +010084 Set the current child process watcher to *watcher*.
Yury Selivanov7c7605f2018-09-11 09:54:40 -070085
86 This function is Unix specific.
87
88
89asyncio ships with the following built-in policies:
90
91
92.. class:: DefaultEventLoopPolicy
93
94 The default asyncio policy. Uses :class:`SelectorEventLoop`
Victor Stinner6ea29c52018-09-25 08:27:08 -070095 on Unix and :class:`ProactorEventLoop` on Windows.
Yury Selivanov7c7605f2018-09-11 09:54:40 -070096
Carol Willing6d9767f2018-09-12 17:09:08 -070097 There is no need to install the default policy manually. asyncio
98 is configured to use the default policy automatically.
Yury Selivanov7c7605f2018-09-11 09:54:40 -070099
Victor Stinner6ea29c52018-09-25 08:27:08 -0700100 .. versionchanged:: 3.8
101
102 On Windows, :class:`ProactorEventLoop` is now used by default.
103
104
105.. class:: WindowsSelectorEventLoopPolicy
106
107 An alternative event loop policy that uses the
108 :class:`SelectorEventLoop` event loop implementation.
109
Cheryl Sabella2d6097d2018-10-12 10:55:20 -0400110 .. availability:: Windows.
Victor Stinner6ea29c52018-09-25 08:27:08 -0700111
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700112
113.. class:: WindowsProactorEventLoopPolicy
114
115 An alternative event loop policy that uses the
116 :class:`ProactorEventLoop` event loop implementation.
117
Cheryl Sabella2d6097d2018-10-12 10:55:20 -0400118 .. availability:: Windows.
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700119
120
121Process Watchers
122================
123
124A process watcher allows customization of how an event loop monitors
125child processes on Unix. Specifically, the event loop needs to know
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -0400126when a child process has exited.
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700127
128In asyncio, child processes are created with
129:func:`create_subprocess_exec` and :meth:`loop.subprocess_exec`
130functions.
131
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -0400132asyncio defines the :class:`AbstractChildWatcher` abstract base class,
133which child watchers should implement, and has two different
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700134implementations: :class:`SafeChildWatcher` (configured to be used
135by default) and :class:`FastChildWatcher`.
136
137See also the :ref:`Subprocess and Threads <asyncio-subprocess-threads>`
138section.
139
Carol Willing6d9767f2018-09-12 17:09:08 -0700140The following two functions can be used to customize the child process watcher
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700141implementation used by the asyncio event loop:
142
143.. function:: get_child_watcher()
144
145 Return the current child watcher for the current policy.
146
147.. function:: set_child_watcher(watcher)
148
149 Set the current child watcher to *watcher* for the current
150 policy. *watcher* must implement methods defined in the
151 :class:`AbstractChildWatcher` base class.
152
153.. note::
154 Third-party event loops implementations might not support
155 custom child watchers. For such event loops, using
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -0400156 :func:`set_child_watcher` might be prohibited or have no effect.
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700157
158.. class:: AbstractChildWatcher
159
160 .. method:: add_child_handler(pid, callback, \*args)
161
162 Register a new child handler.
163
164 Arrange for ``callback(pid, returncode, *args)`` to be called
165 when a process with PID equal to *pid* terminates. Specifying
166 another callback for the same process replaces the previous
167 handler.
168
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -0400169 The *callback* callable must be thread-safe.
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700170
171 .. method:: remove_child_handler(pid)
172
173 Removes the handler for process with PID equal to *pid*.
174
175 The function returns ``True`` if the handler was successfully
176 removed, ``False`` if there was nothing to remove.
177
178 .. method:: attach_loop(loop)
179
180 Attach the watcher to an event loop.
181
182 If the watcher was previously attached to an event loop, then
183 it is first detached before attaching to the new loop.
184
185 Note: loop may be ``None``.
186
187 .. method:: close()
188
189 Close the watcher.
190
191 This method has to be called to ensure that underlying
192 resources are cleaned-up.
193
194.. class:: SafeChildWatcher
195
196 This implementation avoids disrupting other code spawning processes
197 by polling every process explicitly on a :py:data:`SIGCHLD` signal.
198
199 This is a safe solution but it has a significant overhead when
200 handling a big number of processes (*O(n)* each time a
201 :py:data:`SIGCHLD` is received).
202
Carol Willing6d9767f2018-09-12 17:09:08 -0700203 asyncio uses this safe implementation by default.
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700204
205.. class:: FastChildWatcher
206
207 This implementation reaps every terminated processes by calling
208 ``os.waitpid(-1)`` directly, possibly breaking other code spawning
209 processes and waiting for their termination.
210
211 There is no noticeable overhead when handling a big number of
212 children (*O(1)* each time a child terminates).
213
214
215Custom Policies
216===============
217
218To implement a new event loop policy, it is recommended to subclass
219:class:`DefaultEventLoopPolicy` and override the methods for which
220custom behavior is wanted, e.g.::
221
222 class MyEventLoopPolicy(asyncio.DefaultEventLoopPolicy):
223
224 def get_event_loop(self):
225 """Get the event loop.
226
227 This may be None or an instance of EventLoop.
228 """
229 loop = super().get_event_loop()
230 # Do something with loop ...
231 return loop
232
233 asyncio.set_event_loop_policy(MyEventLoopPolicy())