blob: 1838eb95a7d52230336a56faa1c992003af8e8b0 [file] [log] [blame]
Victor Stinnerdb39a0d2014-01-16 18:58:01 +01001.. currentmodule:: asyncio
2
Victor Stinner0f3e6bc2014-02-19 23:15:02 +01003.. _asyncio-dev:
4
Victor Stinnerdb39a0d2014-01-16 18:58:01 +01005Develop with asyncio
6====================
7
8Asynchronous programming is different than classical "sequential" programming.
Eli Bendersky679688e2014-01-20 08:13:31 -08009This page lists common traps and explains how to avoid them.
Victor Stinnerdb39a0d2014-01-16 18:58:01 +010010
11
Victor Stinner62511fd2014-06-23 00:36:11 +020012.. _asyncio-debug-mode:
13
14Debug mode of asyncio
15---------------------
16
Andrew Svetlov49199072015-09-24 14:32:39 +030017The implementation of :mod:`asyncio` has been written for performance.
18In order to ease the development of asynchronous code, you may wish to
19enable *debug mode*.
Victor Stinnerd71dcbb2014-08-25 17:04:12 +020020
Andrew Svetlov49199072015-09-24 14:32:39 +030021To enable all debug checks for an application:
Victor Stinnerd71dcbb2014-08-25 17:04:12 +020022
Victor Stinner6a1b0042015-02-04 16:14:33 +010023* Enable the asyncio debug mode globally by setting the environment variable
Guido van Rossumf68afd82016-08-08 09:41:21 -070024 :envvar:`PYTHONASYNCIODEBUG` to ``1``, or by calling :meth:`AbstractEventLoop.set_debug`.
Victor Stinner6a1b0042015-02-04 16:14:33 +010025* Set the log level of the :ref:`asyncio logger <asyncio-logger>` to
26 :py:data:`logging.DEBUG`. For example, call
27 ``logging.basicConfig(level=logging.DEBUG)`` at startup.
28* Configure the :mod:`warnings` module to display :exc:`ResourceWarning`
29 warnings. For example, use the ``-Wdefault`` command line option of Python to
30 display them.
31
32Examples debug checks:
Victor Stinner62511fd2014-06-23 00:36:11 +020033
34* Log :ref:`coroutines defined but never "yielded from"
35 <asyncio-coroutine-not-scheduled>`
Guido van Rossumf68afd82016-08-08 09:41:21 -070036* :meth:`~AbstractEventLoop.call_soon` and :meth:`~AbstractEventLoop.call_at` methods
Victor Stinner62511fd2014-06-23 00:36:11 +020037 raise an exception if they are called from the wrong thread.
38* Log the execution time of the selector
39* Log callbacks taking more than 100 ms to be executed. The
Guido van Rossumf68afd82016-08-08 09:41:21 -070040 :attr:`AbstractEventLoop.slow_callback_duration` attribute is the minimum
Victor Stinner62511fd2014-06-23 00:36:11 +020041 duration in seconds of "slow" callbacks.
Victor Stinner6a1b0042015-02-04 16:14:33 +010042* :exc:`ResourceWarning` warnings are emitted when transports and event loops
43 are :ref:`not closed explicitly <asyncio-close-transports>`.
Victor Stinner62511fd2014-06-23 00:36:11 +020044
45.. seealso::
46
Guido van Rossumf68afd82016-08-08 09:41:21 -070047 The :meth:`AbstractEventLoop.set_debug` method and the :ref:`asyncio logger
Victor Stinner62511fd2014-06-23 00:36:11 +020048 <asyncio-logger>`.
49
50
Victor Stinner1077dee2015-01-30 00:55:58 +010051Cancellation
52------------
53
54Cancellation of tasks is not common in classic programming. In asynchronous
Mike DePalatis87c3c5d2017-08-03 10:20:42 -040055programming, not only is it something common, but you have to prepare your
Victor Stinner1077dee2015-01-30 00:55:58 +010056code to handle it.
57
58Futures and tasks can be cancelled explicitly with their :meth:`Future.cancel`
59method. The :func:`wait_for` function cancels the waited task when the timeout
60occurs. There are many other cases where a task can be cancelled indirectly.
61
62Don't call :meth:`~Future.set_result` or :meth:`~Future.set_exception` method
63of :class:`Future` if the future is cancelled: it would fail with an exception.
64For example, write::
65
66 if not fut.cancelled():
67 fut.set_result('done')
68
69Don't schedule directly a call to the :meth:`~Future.set_result` or the
70:meth:`~Future.set_exception` method of a future with
Guido van Rossumf68afd82016-08-08 09:41:21 -070071:meth:`AbstractEventLoop.call_soon`: the future can be cancelled before its method
Victor Stinner1077dee2015-01-30 00:55:58 +010072is called.
73
74If you wait for a future, you should check early if the future was cancelled to
75avoid useless operations. Example::
76
77 @coroutine
78 def slow_operation(fut):
79 if fut.cancelled():
80 return
81 # ... slow computation ...
82 yield from fut
83 # ...
84
85The :func:`shield` function can also be used to ignore cancellation.
86
87
Victor Stinner606ab032014-02-01 03:18:58 +010088.. _asyncio-multithreading:
89
90Concurrency and multithreading
91------------------------------
92
93An event loop runs in a thread and executes all callbacks and tasks in the same
Victor Stinner86516d92014-02-18 09:22:00 +010094thread. While a task is running in the event loop, no other task is running in
Victor Stinner5cb84ed2014-02-04 18:18:27 +010095the same thread. But when the task uses ``yield from``, the task is suspended
96and the event loop executes the next task.
Victor Stinner606ab032014-02-01 03:18:58 +010097
Victor Stinner5cb84ed2014-02-04 18:18:27 +010098To schedule a callback from a different thread, the
Guido van Rossumf68afd82016-08-08 09:41:21 -070099:meth:`AbstractEventLoop.call_soon_threadsafe` method should be used. Example::
Victor Stinner5cb84ed2014-02-04 18:18:27 +0100100
Guido van Rossum601953b2015-10-05 16:20:00 -0700101 loop.call_soon_threadsafe(callback, *args)
Victor Stinner606ab032014-02-01 03:18:58 +0100102
Victor Stinner790202d2014-02-07 19:03:05 +0100103Most asyncio objects are not thread safe. You should only worry if you access
104objects outside the event loop. For example, to cancel a future, don't call
105directly its :meth:`Future.cancel` method, but::
106
107 loop.call_soon_threadsafe(fut.cancel)
108
Victor Stinner606ab032014-02-01 03:18:58 +0100109To handle signals and to execute subprocesses, the event loop must be run in
110the main thread.
111
Guido van Rossum601953b2015-10-05 16:20:00 -0700112To schedule a coroutine object from a different thread, the
113:func:`run_coroutine_threadsafe` function should be used. It returns a
114:class:`concurrent.futures.Future` to access the result::
115
116 future = asyncio.run_coroutine_threadsafe(coro_func(), loop)
117 result = future.result(timeout) # Wait for the result with a timeout
118
Guido van Rossumf68afd82016-08-08 09:41:21 -0700119The :meth:`AbstractEventLoop.run_in_executor` method can be used with a thread pool
Victor Stinner606ab032014-02-01 03:18:58 +0100120executor to execute a callback in different thread to not block the thread of
121the event loop.
122
123.. seealso::
124
Zachary Ware5819cfa2015-01-06 00:40:43 -0600125 The :ref:`Synchronization primitives <asyncio-sync>` section describes ways
126 to synchronize tasks.
Victor Stinner606ab032014-02-01 03:18:58 +0100127
Victor Stinner399c59d2015-01-09 01:32:02 +0100128 The :ref:`Subprocess and threads <asyncio-subprocess-threads>` section lists
129 asyncio limitations to run subprocesses from different threads.
130
131
132
Victor Stinner606ab032014-02-01 03:18:58 +0100133
Victor Stinner45b27ed2014-02-01 02:36:43 +0100134.. _asyncio-handle-blocking:
135
Eli Benderskyb73c8332014-02-09 06:07:47 -0800136Handle blocking functions correctly
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100137-----------------------------------
138
139Blocking functions should not be called directly. For example, if a function
140blocks for 1 second, other tasks are delayed by 1 second which can have an
141important impact on reactivity.
142
143For networking and subprocesses, the :mod:`asyncio` module provides high-level
Victor Stinner9592edb2014-02-02 15:03:02 +0100144APIs like :ref:`protocols <asyncio-protocol>`.
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100145
146An executor can be used to run a task in a different thread or even in a
147different process, to not block the thread of the event loop. See the
Guido van Rossumf68afd82016-08-08 09:41:21 -0700148:meth:`AbstractEventLoop.run_in_executor` method.
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100149
Victor Stinner45b27ed2014-02-01 02:36:43 +0100150.. seealso::
151
152 The :ref:`Delayed calls <asyncio-delayed-calls>` section details how the
153 event loop handles time.
154
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100155
156.. _asyncio-logger:
157
Victor Stinner45b27ed2014-02-01 02:36:43 +0100158Logging
159-------
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100160
Victor Stinner45b27ed2014-02-01 02:36:43 +0100161The :mod:`asyncio` module logs information with the :mod:`logging` module in
162the logger ``'asyncio'``.
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100163
Guido van Rossumba29a4f2016-10-13 13:56:40 -0700164The default log level for the :mod:`asyncio` module is :py:data:`logging.INFO`.
165For those not wanting such verbosity from :mod:`asyncio` the log level can
166be changed. For example, to change the level to :py:data:`logging.WARNING`:
167
168.. code-block:: none
169
170 logging.getLogger('asyncio').setLevel(logging.WARNING)
171
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100172
173.. _asyncio-coroutine-not-scheduled:
174
175Detect coroutine objects never scheduled
176----------------------------------------
177
Victor Stinner530ef2f2014-07-08 12:39:10 +0200178When a coroutine function is called and its result is not passed to
Guido van Rossumf68afd82016-08-08 09:41:21 -0700179:func:`ensure_future` or to the :meth:`AbstractEventLoop.create_task` method,
Yury Selivanov04356e12015-06-30 22:13:22 -0400180the execution of the coroutine object will never be scheduled which is
181probably a bug. :ref:`Enable the debug mode of asyncio <asyncio-debug-mode>`
182to :ref:`log a warning <asyncio-logger>` to detect it.
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100183
184Example with the bug::
185
186 import asyncio
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100187
188 @asyncio.coroutine
189 def test():
190 print("never scheduled")
191
192 test()
193
194Output in debug mode::
195
Victor Stinner530ef2f2014-07-08 12:39:10 +0200196 Coroutine test() at test.py:3 was never yielded from
197 Coroutine object created at (most recent call last):
198 File "test.py", line 7, in <module>
199 test()
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100200
Yury Selivanov04356e12015-06-30 22:13:22 -0400201The fix is to call the :func:`ensure_future` function or the
Guido van Rossumf68afd82016-08-08 09:41:21 -0700202:meth:`AbstractEventLoop.create_task` method with the coroutine object.
Victor Stinner530ef2f2014-07-08 12:39:10 +0200203
204.. seealso::
205
206 :ref:`Pending task destroyed <asyncio-pending-task-destroyed>`.
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100207
208
Victor Stinner530ef2f2014-07-08 12:39:10 +0200209Detect exceptions never consumed
210--------------------------------
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100211
212Python usually calls :func:`sys.displayhook` on unhandled exceptions. If
Victor Stinner530ef2f2014-07-08 12:39:10 +0200213:meth:`Future.set_exception` is called, but the exception is never consumed,
Zachary Ware5819cfa2015-01-06 00:40:43 -0600214:func:`sys.displayhook` is not called. Instead, :ref:`a log is emitted
Victor Stinner530ef2f2014-07-08 12:39:10 +0200215<asyncio-logger>` when the future is deleted by the garbage collector, with the
216traceback where the exception was raised.
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100217
218Example of unhandled exception::
219
220 import asyncio
221
222 @asyncio.coroutine
223 def bug():
224 raise Exception("not consumed")
225
226 loop = asyncio.get_event_loop()
Yury Selivanovd7e19bb2015-05-11 16:33:41 -0400227 asyncio.ensure_future(bug())
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100228 loop.run_forever()
Victor Stinnerb8064a82015-02-23 11:41:56 +0100229 loop.close()
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100230
231Output::
232
Victor Stinner530ef2f2014-07-08 12:39:10 +0200233 Task exception was never retrieved
Victor Stinnerab1c8532014-10-12 21:37:16 +0200234 future: <Task finished coro=<coro() done, defined at asyncio/coroutines.py:139> exception=Exception('not consumed',)>
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100235 Traceback (most recent call last):
Victor Stinnerab1c8532014-10-12 21:37:16 +0200236 File "asyncio/tasks.py", line 237, in _step
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100237 result = next(coro)
Victor Stinner530ef2f2014-07-08 12:39:10 +0200238 File "asyncio/coroutines.py", line 141, in coro
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100239 res = func(*args, **kw)
Victor Stinnerab1c8532014-10-12 21:37:16 +0200240 File "test.py", line 5, in bug
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100241 raise Exception("not consumed")
242 Exception: not consumed
243
Victor Stinner530ef2f2014-07-08 12:39:10 +0200244:ref:`Enable the debug mode of asyncio <asyncio-debug-mode>` to get the
Victor Stinnerab1c8532014-10-12 21:37:16 +0200245traceback where the task was created. Output in debug mode::
246
247 Task exception was never retrieved
248 future: <Task finished coro=<bug() done, defined at test.py:3> exception=Exception('not consumed',) created at test.py:8>
249 source_traceback: Object created at (most recent call last):
250 File "test.py", line 8, in <module>
Yury Selivanovd7e19bb2015-05-11 16:33:41 -0400251 asyncio.ensure_future(bug())
Victor Stinnerab1c8532014-10-12 21:37:16 +0200252 Traceback (most recent call last):
253 File "asyncio/tasks.py", line 237, in _step
254 result = next(coro)
255 File "asyncio/coroutines.py", line 79, in __next__
256 return next(self.gen)
257 File "asyncio/coroutines.py", line 141, in coro
258 res = func(*args, **kw)
259 File "test.py", line 5, in bug
260 raise Exception("not consumed")
261 Exception: not consumed
Victor Stinner530ef2f2014-07-08 12:39:10 +0200262
Zachary Ware5819cfa2015-01-06 00:40:43 -0600263There are different options to fix this issue. The first option is to chain the
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100264coroutine in another coroutine and use classic try/except::
265
266 @asyncio.coroutine
267 def handle_exception():
268 try:
269 yield from bug()
270 except Exception:
271 print("exception consumed")
272
273 loop = asyncio.get_event_loop()
Yury Selivanovd7e19bb2015-05-11 16:33:41 -0400274 asyncio.ensure_future(handle_exception())
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100275 loop.run_forever()
Victor Stinnerb8064a82015-02-23 11:41:56 +0100276 loop.close()
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100277
Guido van Rossumf68afd82016-08-08 09:41:21 -0700278Another option is to use the :meth:`AbstractEventLoop.run_until_complete`
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100279function::
280
Yury Selivanovd7e19bb2015-05-11 16:33:41 -0400281 task = asyncio.ensure_future(bug())
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100282 try:
283 loop.run_until_complete(task)
284 except Exception:
285 print("exception consumed")
286
Zachary Ware5819cfa2015-01-06 00:40:43 -0600287.. seealso::
288
289 The :meth:`Future.exception` method.
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100290
291
Zachary Ware5819cfa2015-01-06 00:40:43 -0600292Chain coroutines correctly
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100293--------------------------
294
295When a coroutine function calls other coroutine functions and tasks, they
Eli Bendersky679688e2014-01-20 08:13:31 -0800296should be chained explicitly with ``yield from``. Otherwise, the execution is
297not guaranteed to be sequential.
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100298
Eli Bendersky679688e2014-01-20 08:13:31 -0800299Example with different bugs using :func:`asyncio.sleep` to simulate slow
300operations::
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100301
302 import asyncio
303
304 @asyncio.coroutine
305 def create():
306 yield from asyncio.sleep(3.0)
307 print("(1) create file")
308
309 @asyncio.coroutine
310 def write():
311 yield from asyncio.sleep(1.0)
312 print("(2) write into file")
313
314 @asyncio.coroutine
315 def close():
316 print("(3) close file")
317
318 @asyncio.coroutine
319 def test():
Yury Selivanovd7e19bb2015-05-11 16:33:41 -0400320 asyncio.ensure_future(create())
321 asyncio.ensure_future(write())
322 asyncio.ensure_future(close())
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100323 yield from asyncio.sleep(2.0)
324 loop.stop()
325
326 loop = asyncio.get_event_loop()
Yury Selivanovd7e19bb2015-05-11 16:33:41 -0400327 asyncio.ensure_future(test())
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100328 loop.run_forever()
329 print("Pending tasks at exit: %s" % asyncio.Task.all_tasks(loop))
Victor Stinnerf40c6632014-01-28 23:32:40 +0100330 loop.close()
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100331
Martin Panter1050d2d2016-07-26 11:18:21 +0200332Expected output:
333
334.. code-block:: none
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100335
336 (1) create file
337 (2) write into file
338 (3) close file
339 Pending tasks at exit: set()
340
Martin Panter1050d2d2016-07-26 11:18:21 +0200341Actual output:
342
343.. code-block:: none
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100344
345 (3) close file
346 (2) write into file
Victor Stinner530ef2f2014-07-08 12:39:10 +0200347 Pending tasks at exit: {<Task pending create() at test.py:7 wait_for=<Future pending cb=[Task._wakeup()]>>}
348 Task was destroyed but it is pending!
349 task: <Task pending create() done at test.py:5 wait_for=<Future pending cb=[Task._wakeup()]>>
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100350
351The loop stopped before the ``create()`` finished, ``close()`` has been called
352before ``write()``, whereas coroutine functions were called in this order:
353``create()``, ``write()``, ``close()``.
354
355To fix the example, tasks must be marked with ``yield from``::
356
357 @asyncio.coroutine
358 def test():
Yury Selivanovd7e19bb2015-05-11 16:33:41 -0400359 yield from asyncio.ensure_future(create())
360 yield from asyncio.ensure_future(write())
361 yield from asyncio.ensure_future(close())
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100362 yield from asyncio.sleep(2.0)
363 loop.stop()
364
Yury Selivanovd7e19bb2015-05-11 16:33:41 -0400365Or without ``asyncio.ensure_future()``::
Victor Stinnerdb39a0d2014-01-16 18:58:01 +0100366
367 @asyncio.coroutine
368 def test():
369 yield from create()
370 yield from write()
371 yield from close()
372 yield from asyncio.sleep(2.0)
373 loop.stop()
374
Victor Stinner530ef2f2014-07-08 12:39:10 +0200375
376.. _asyncio-pending-task-destroyed:
377
378Pending task destroyed
379----------------------
380
381If a pending task is destroyed, the execution of its wrapped :ref:`coroutine
382<coroutine>` did not complete. It is probably a bug and so a warning is logged.
383
Martin Panter1050d2d2016-07-26 11:18:21 +0200384Example of log:
385
386.. code-block:: none
Victor Stinner530ef2f2014-07-08 12:39:10 +0200387
388 Task was destroyed but it is pending!
Victor Stinnerab1c8532014-10-12 21:37:16 +0200389 task: <Task pending coro=<kill_me() done, defined at test.py:5> wait_for=<Future pending cb=[Task._wakeup()]>>
Victor Stinner530ef2f2014-07-08 12:39:10 +0200390
391:ref:`Enable the debug mode of asyncio <asyncio-debug-mode>` to get the
Martin Panter1050d2d2016-07-26 11:18:21 +0200392traceback where the task was created. Example of log in debug mode:
393
394.. code-block:: none
Victor Stinnerab1c8532014-10-12 21:37:16 +0200395
396 Task was destroyed but it is pending!
397 source_traceback: Object created at (most recent call last):
398 File "test.py", line 15, in <module>
Yury Selivanovd7e19bb2015-05-11 16:33:41 -0400399 task = asyncio.ensure_future(coro, loop=loop)
Victor Stinnerab1c8532014-10-12 21:37:16 +0200400 task: <Task pending coro=<kill_me() done, defined at test.py:5> wait_for=<Future pending cb=[Task._wakeup()] created at test.py:7> created at test.py:15>
401
Victor Stinner530ef2f2014-07-08 12:39:10 +0200402
403.. seealso::
404
405 :ref:`Detect coroutine objects never scheduled <asyncio-coroutine-not-scheduled>`.
406
Victor Stinner6a1b0042015-02-04 16:14:33 +0100407.. _asyncio-close-transports:
Victor Stinner188f2c02015-01-30 01:35:14 +0100408
Victor Stinner6a1b0042015-02-04 16:14:33 +0100409Close transports and event loops
410--------------------------------
Victor Stinner188f2c02015-01-30 01:35:14 +0100411
412When a transport is no more needed, call its ``close()`` method to release
Victor Stinner6a1b0042015-02-04 16:14:33 +0100413resources. Event loops must also be closed explicitly.
Victor Stinner188f2c02015-01-30 01:35:14 +0100414
Victor Stinner6a1b0042015-02-04 16:14:33 +0100415If a transport or an event loop is not closed explicitly, a
416:exc:`ResourceWarning` warning will be emitted in its destructor. By default,
417:exc:`ResourceWarning` warnings are ignored. The :ref:`Debug mode of asyncio
418<asyncio-debug-mode>` section explains how to display them.