Doc rework to use the async/await syntax.

This commit is contained in:
Nicolas Di Pietro 2016-07-10 15:42:15 +02:00
parent b35eabd9bc
commit 4cd97d47df
3 changed files with 35 additions and 47 deletions

View File

@ -272,7 +272,7 @@ Have a look at the highlighted lines - here is what we do:
.. note::
The reason ``returnValue`` is necessary goes deep into implementation details of Twisted and Python. In short: co-routines in Python 2 with Twisted are simulated using exceptions. Only Python 3.3+ has gotten native support for co-routines using the new yield from statement.
The reason ``returnValue`` is necessary goes deep into implementation details of Twisted and Python. In short: co-routines in Python 2 with Twisted are simulated using exceptions. Only Python 3.3+ has gotten native support for co-routines using the new yield from statement, Python 3.5+ use await statement and it is the new recommended method.
In above, we are using a little helper :func:`autobahn.twisted.util.sleep` for sleeping "inline". The helper is really trivial:
@ -298,7 +298,7 @@ Asyncio Futures and Coroutines
On the other hand, asyncio futures are quite different from Twisted Deferreds. One difference is that they have no built-in machinery for chaining.
`Asyncio Coroutines <http://docs.python.org/3.4/library/asyncio-task.html#coroutines>`__ are (on a certain level) quite similar to Twisted inline callbacks. Here is the code corresponding to our example above:
`Asyncio Coroutines <http://docs.python.org/3.5/library/asyncio-task.html#coroutines>`__ are (on a certain level) quite similar to Twisted inline callbacks. Here is the code corresponding to our example above:
-------
@ -355,19 +355,17 @@ Now, when converted to ``asyncio.coroutine``, the code becomes:
.. code-block:: python
:linenos:
:emphasize-lines: 3,5,6
:emphasize-lines: 3,4,5
import asyncio
@asyncio.coroutine
def slow_square(x):
yield from asyncio.sleep(1)
async def slow_square(x):
await asyncio.sleep(1)
return x * x
@asyncio.coroutine
def test():
res = yield from slow_square(3)
async def test():
res = await slow_square(3)
print(res)
loop = asyncio.get_event_loop()
@ -375,9 +373,9 @@ Now, when converted to ``asyncio.coroutine``, the code becomes:
The main differences (on surface) are:
1. The use of the decorator ``@asyncio.coroutine`` (line 3) in asyncio versus ``@defer.inlineCallbacks`` with Twisted
1. The declaration of the function with ``async`` keyword (line 3) in asyncio versus the decorator ``@defer.inlineCallbacks`` with Twisted
2. The use of ``defer.returnValue`` in Twisted for returning values whereas in asyncio, you can use plain returns (line 6)
3. The use of ``yield from`` in asyncio, versus plain ``yield`` in Twisted (line 5)
3. The use of ``await`` in asyncio, versus ``yield`` in Twisted (line 5)
4. The auxiliary code to get the event loop started and stopped
Most of the examples that follow will show code for both Twisted and asyncio, unless the conversion is trivial.

View File

@ -144,18 +144,16 @@ Here are quick templates for you to copy/paste for creating and running a WAMP c
**asyncio**:
.. code-block:: python
:emphasize-lines: 2
:emphasize-lines: 1
from asyncio import coroutine
from autobahn.asyncio.wamp import ApplicationSession, ApplicationRunner
class MyComponent(ApplicationSession):
@coroutine
def onJoin(self, details):
async def onJoin(self, details):
print("session joined")
# can do subscribes, registers here e.g.:
# yield from self.subscribe(...)
# yield from self.register(...)
# await self.subscribe(...)
# await self.register(...)
if __name__ == '__main__':
runner = ApplicationRunner(url=u"ws://localhost:8080/ws", realm=u"realm1")
@ -248,21 +246,19 @@ Using **asyncio**, the example looks like this:
.. code-block:: python
:linenos:
:emphasize-lines: 13
:emphasize-lines: 11
from autobahn.asyncio.wamp import ApplicationSession
from asyncio import coroutine
class MyComponent(ApplicationSession):
@coroutine
def onJoin(self, details):
async def onJoin(self, details):
print("session ready")
def add2(x, y):
return x + y
try:
yield from self.register(add2, u'com.myapp.add2')
await self.register(add2, u'com.myapp.add2')
print("procedure registered")
except Exception as e:
print("could not register procedure: {0}".format(e))
@ -270,8 +266,8 @@ Using **asyncio**, the example looks like this:
The differences compared with the Twisted variant are:
* the ``import`` of ``ApplicationSession``
* the use of ``@coroutine`` to decorate co-routines
* the use of ``yield from`` instead of ``yield``
* the use of ``async`` keyword to declare co-routines
* the use of ``await`` instead of ``yield``
.. _calling-procedures:
@ -306,19 +302,17 @@ And here is the same done on **asyncio**
.. code-block:: python
:linenos:
:emphasize-lines: 11
:emphasize-lines: 9
from autobahn.asyncio.wamp import ApplicationSession
from asyncio import coroutine
class MyComponent(ApplicationSession):
@coroutine
def onJoin(self, details):
async def onJoin(self, details):
print("session ready")
try:
res = yield from self.call(u'com.myapp.add2', 2, 3)
res = await self.call(u'com.myapp.add2', 2, 3)
print("call result: {}".format(res))
except Exception as e:
print("call error: {0}".format(e))
@ -383,22 +377,20 @@ The corresponding **asyncio** code looks like this
.. code-block:: python
:linenos:
:emphasize-lines: 14
:emphasize-lines: 12
from autobahn.asyncio.wamp import ApplicationSession
from asyncio import coroutine
class MyComponent(ApplicationSession):
@coroutine
def onJoin(self, details):
async def onJoin(self, details):
print("session ready")
def oncounter(count):
print("event received: {0}", count)
try:
yield from self.subscribe(oncounter, u'com.myapp.oncounter')
await self.subscribe(oncounter, u'com.myapp.oncounter')
print("subscribed to topic")
except Exception as e:
print("could not subscribe to topic: {0}".format(e))
@ -441,23 +433,21 @@ The corresponding **asyncio** code looks like this
.. code-block:: python
:linenos:
:emphasize-lines: 13
:emphasize-lines: 11
from autobahn.asyncio.wamp import ApplicationSession
from asyncio import sleep
from asyncio import coroutine
class MyComponent(ApplicationSession):
@coroutine
def onJoin(self, details):
async def onJoin(self, details):
print("session ready")
counter = 0
while True:
self.publish(u'com.myapp.oncounter', counter)
counter += 1
yield from sleep(1)
await sleep(1)
.. tip::

View File

@ -15,7 +15,7 @@ For example, here is how you call a remote procedure that takes no arguments and
print(now)
This is using `yield`, which assumes the context in that you run this code is a *co-routine* (something decorated with `defer.inlineDeferred` in Twisted or `asyncio.coroutine` in asyncio).
This is using `yield`, which assumes the context in that you run this code is a *co-routine* (something decorated with `defer.inlineDeferred` in Twisted or declared with `async def` in asyncio).
The same call using plain Twisted Deferreds would look like:
@ -183,7 +183,7 @@ The direct asyncio equivalent of above would be:
import functools
def print_sales(product, future):
async def print_sales(product, future):
sales = future.result()
print("Sales {}: {}".format(product, sales))
@ -192,7 +192,7 @@ The direct asyncio equivalent of above would be:
f = session.call("com.myapp.sales_by_product", product)
f.add_done_callback(functools.partial(print_sales, product))
fl.append(f)
yield from asyncio.gather(*fl)
await asyncio.gather(*fl)
> Note: Part of the verbosity stems from the fact that, different from Twisted's `addCallback`, asyncio's `add_done_callback` sadly does not take and forward `args` and `kwargs` to the callback added.
>
@ -201,12 +201,12 @@ However, there is a better way, if we restructure the code a litte:
.. code-block:: python
def get_and_print_sales(product):
sales = yield from session.call("com.myapp.sales_by_product", product)
async def get_and_print_sales(product):
sales = await session.call("com.myapp.sales_by_product", product)
print("Sales {}: {}".format(product, sales))
tasks = [get_and_print_sales(product) for product in ["product2", "product3", "product5"]]
yield from asyncio.wait(tasks)
await asyncio.wait(tasks)
Calls with complex results
..........................
@ -248,7 +248,7 @@ Using asyncio coroutines (`asyncio.coroutine`):
.. code-block:: python
try:
res = yield from session.call("com.calculator.sqrt", -1)
res = await session.call("com.calculator.sqrt", -1)
except ApplicationError as err:
print("Error: {}".format(err))
else:
@ -480,7 +480,7 @@ In asyncio, use
.. code-block:: python
registrations = yield from asyncio.gather(*session.register(calc))
registrations = await asyncio.gather(*session.register(calc))
to yield a list of registrations.