Skip to content

Commit 112598e

Browse files
committed
Doc: demote compatibility mode
the code is still there, for now, but …
1 parent 5b6496d commit 112598e

2 files changed

Lines changed: 33 additions & 90 deletions

File tree

docs/source/index.rst

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,28 @@ trio-asyncio: A re-implementation of the asyncio mainloop on top of Trio
1111
Trio-Asyncio is *the* library of choice for a Python program that
1212
contains both `trio`_ and `asyncio`_ code.
1313

14+
.. _trio: https://trio.readtedocs.io
15+
1416
.. _asyncio: https://docs.python.org/3/library/asyncio.html
1517

1618
With trio-asyncio, you can:
1719

1820
* incrementally convert your code to Trio. Start with a Trio mainloop, call
1921
your existing asyncio code, then successively convert procedures to Trio
20-
conventions.
22+
calling conventions.
2123

2224
* use any asyncio-capable library.
2325

2426
* use trio-asyncio as a building block for convincing other async-ish
2527
libraries (Twisted, Promise, …) to be compatible with Trio.
2628

27-
Trio-Asyncio passes the complete Python 3.6 test suite for asyncio. The
28-
test suites for some well-known libraries like aiohttp also Just Work.
29+
Trio-Asyncio passes the test suite of some complex programs like
30+
``home-assistant``.
2931

30-
There's also compatibility code for not running the asyncio loop
31-
continuously, as in repeated run_until_complete / run_forever-and-call-stop
32-
calls. This mode will probably not be supported forever, but for now it works
33-
well.
32+
In the past, the complete Python 3.6 test suite for asyncio and the tests
33+
for some well-known libraries like aiohttp also Just Work(ed). This is no
34+
longer the case because these tests rely heavily on stopping and restarting
35+
the ``asyncio`` event loop. ``trio_asyncio`` no longer supports this.
3436

3537
Helpful facts:
3638

docs/source/usage.rst

Lines changed: 24 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -94,108 +94,49 @@ You cannot restart the loop, nor would you want to.
9494
Asyncio main loop.
9595
++++++++++++++++++
9696

97-
Short answer: don't.
97+
Doesn't work. However: read on.
9898

9999
.. _native-loop:
100100

101-
Native Mode
102-
-----------
103-
104-
What you really want to do is to use a Trio main loop, and run your asyncio
105-
code in its context. In other words, you should transform this code::
101+
What you really want to do is to use a Trio main loop. You then run your
102+
complete asyncio code in its context. In other words, you should transform
103+
this code::
106104

107105
def main():
108106
loop = asyncio.get_event_loop()
109107
loop.run_until_complete(async_main())
110108
109+
or (Python 3.7 ++)::
110+
111+
def main():
112+
asyncio.run(async_main())
113+
111114
to this::
112115

113116
async def trio_main():
114-
await loop.run_asyncio(async_main)
117+
await trio_asyncio.run_asyncio(async_main)
115118

116119
def main():
117120
trio_asyncio.run(trio_main)
118121

119-
Beside this, no changes to your code are required.
120-
121-
Compatibility Mode
122-
------------------
123-
124-
You still can do things "the asyncio way": the to-be-replaced code from the
125-
:ref:`previous section <native-loop>`
126-
still works – or at least it attempts to work::
127-
128-
import asyncio
129-
import trio_asyncio
130-
asyncio.set_event_loop_policy(trio_asyncio.TrioPolicy())
131-
132-
def main():
133-
loop = asyncio.get_event_loop()
134-
loop.run_until_complete(async_main())
135-
136-
.. warning::
137-
138-
tl;dr: Don't use Compatibility Mode in production code.
139-
140-
However, this is only possible because this mode starts a separate thread
141-
which executes the asyncio main
142-
loop. It runs in lock-step with the code that calls ``loop.run_forever()``
143-
or ``loop.run_until_complete(coro)``. Signals etc. get
144-
delegated if possible (except for [SIGCHLD]_). Thus, while there should be no
145-
concurrency issues, you may still experience hard-to-debug problems.
146-
147-
.. [SIGCHLD] Python requires you to register SIGCHLD handlers in the main
148-
thread, but doesn't run them at all when waiting for another thread.
149-
150-
Use :func:`trio_asyncio.wait_for_child` instead.
122+
That's all you need to to to support cross-calling from asyncio to trio
123+
code, or vice versa. You still need to use adapters, though:
124+
:ref:`see below <cross-calling>` for details.
151125

152-
.. autodoc: trio_asyncio.wait_for_child
126+
If your program's start-up code consists of more than one
127+
``loop.run_until_complete`` or ``loop.run_forever`` calls, and/or it
128+
accesses the asyncio mainloop outside of these two calls, you may have to
129+
do some refactoring. Sorry about that.
153130

154-
``loop.stop()`` tells the loop to suspend itself. You can restart it
155-
with another call to ``loop.run_forever()`` or ``loop.run_until_complete(coro)``,
156-
just as with a regular asyncio loop.
157-
158-
If you use a compatibility-mode loop in a separate thread, you *must* stop and close it
159-
before terminating that thread. Otherwise your thread will leak resources.
160-
161-
In a multi-threaded program, globally setting the event loop policy may not
162-
be a good idea. If you want to run trio-asyncio in a separate thread, you
163-
might get away with using ``TrioPolicy().new_event_loop()`` to create a new
164-
event loop – but a far better idea is to use native mode.
165-
166-
.. note::
167-
168-
Compatibility mode has been added to verify that various test suites,
169-
most notably the tests from asyncio itself, continue to work. In a
170-
real-world program with a long-running asyncio mainloop, you *really*
171-
want to use a :ref:`native-mode main loop <native-loop>` instead.
172-
173-
The authors reserve the right to not fix compatibility mode bugs, or
174-
even to remove compatibility mode entirely.
175-
176-
.. autoclass:: trio_asyncio.sync.SyncTrioEventLoop
177-
178-
Stopping
179-
--------
180-
181-
Call ``loop.stop()`` as usual.
182-
183-
Before stopping, the loop will process all outstanding callbacks.
184-
185-
Closing
186-
-------
187-
188-
A synchronous loop starts a separate thread for running the asynchronous
189-
part of your code. You **must** call ``loop.close()`` before abandoning the
190-
loop.
131+
Compatibility mode
132+
++++++++++++++++++
191133

192-
.. note::
134+
… or, running ``trio_asyncio`` on top of an unmodified '`asyncio`` main loop.
193135

194-
This is not a problem in "normal" programs – when the program
195-
terminates, the loop dies along with it. However, when testing you don't
196-
want to leave 1000 asyncio threads lying around.
197-
198-
This also applies in multi-threaded programs with more than one event loop.
136+
Unfortunately, we had to discontinue support for this mode. The code was
137+
too intrusive and not particularly stable, caused problems with debugging,
138+
and crashed asyncio when trio_asyncio was imported after starting the
139+
asyncio mainloop.
199140

200141
---------------
201142
Cross-calling

0 commit comments

Comments
 (0)