blob: cc4a14b2016226cc90d717e8f2c65f686dd35a60 [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
55programming, not only it is something common, but you have to prepare your
56code 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.