SlideShare une entreprise Scribd logo
1  sur  30
Télécharger pour lire hors ligne
Пишем для
asyncio
Андрей Светлов
О себе
● Python Core Developer
● Принимал участие в создании asyncio
● Соавтор нескольких библиотек на основе
asyncio — aiohttp, aiozmq, aiopg
● Использую asyncio на работе
yield from
import asyncio
@asyncio.coroutine
def task():
resp = yield from aiohttp.request('GET', 'http://python.org')
if resp.status == 200:
body = yield from resp.read()
print(body)
resp.close()
asyncio.get_event_loop().run_until_complete(task())
Упрощенный yield from
for i in EXPR:
yield i
i.send(val)
i.throw(exc)
i.close()
Полный вариант yield from
_i = iter(EXPR)
try:
_y = next(_i)
except StopIteration as _e:
_r = _e.value
else:
while 1:
try:
_s = yield _y
except GeneratorExit as _e:
try:
_m = _i.close
except AttributeError:
pass
else:
_m()
raise _e
except BaseException as _e:
_x = sys.exc_info()
try:
_m = _i.throw
except AttributeError:
raise _e
else:
try:
_y = _m(*_x)
except StopIteration as _e:
_r = _e.value
break
else:
try:
if _s is None:
_y = next(_i)
else:
_y = _i.send(_s)
except StopIteration as _e:
_r = _e.value
break
RESULT = _r
yield против yield from
● программный стек
● неудобные stack
trace
● неприятная
отладка
● Медленней в 20
раз
Всё ровно наоборот
:)
Stack trace
@asyncio.coroutine
def inner():
raise RuntimeError("Ooops!")
@asyncio.coroutine
def outer():
yield from inner()
loop = asyncio.get_event_loop()
loop.run_until_complete(outer())
Traceback (most recent call last):
File "s.py", line 13, in <module>
loop.run_until_complete(outer())
File ".../asyncio/base_events.py", line 208, in
run_until_complete
return future.result()
File ".../asyncio/futures.py", line 243, in result
raise self._exception
File ".../asyncio/tasks.py", line 302, in _step
result = next(coro)
File "s.py", line 9, in outer
yield from inner()
File ".../asyncio/tasks.py", line 84, in coro
res = func(*args, **kw)
File "s.py", line 5, in inner
raise RuntimeError("Ooops!")
RuntimeError: Ooops!
Debug режим
@asyncio.coroutine
def f():
asyncio.sleep(10) # missing yield from
loop = asyncio.get_event_loop()
loop.run_until_complete(f())
Переменная окружения PYTHONASYNCIODEBUG
$ PYTHONASYNCIODEBUG=1 python3 d.py
Coroutine 'sleep' defined at /usr/lib/python3.4/asyncio/tasks.py:542 was never
yielded from
Отладка
def g():
ret = yield from f()
● next
● step
Переключение контекста
def transfer(amount, payer, payee, server):
if not payer.sufficient_funds_for_withdrawl(amount):
raise InsufficientFunds()
log("{payer} has sufficient funds.", payer=payer)
payee.deposit(amount)
log("{payee} received payment", payee=payee)
payer.withdraw(amount)
log("{payer} made payment", payer=payer)
server.update_balances([payer, payee])
Переключение контекста 2
@coroutine
def transfer(amount, payer, payee, server):
if not payer.sufficient_funds_for_withdrawl(amount):
raise InsufficientFunds()
log("{payer} has sufficient funds.", payer=payer)
payee.deposit(amount)
log("{payee} received payment", payee=payee)
payer.withdraw(amount)
log("{payer} made payment", payer=payer)
yield from server.update_balances([payer, payee])
Переключение контекста 3
@coroutine
def transfer(amount, payer, payee, server):
if not payer.sufficient_funds_for_withdrawl(amount):
raise InsufficientFunds()
yield from log("{payer} has sufficient funds.", payer=payer)
payee.deposit(amount)
yield from log("{payee} received payment", payee=payee)
payer.withdraw(amount)
yield from log("{payer} made payment", payer=payer)
yield from server.update_balances([payer, payee])
Переключение контекста 4
@coroutine
def transfer(amount, payer, payee, server):
with (yield from payer.hold(amount):
if not payer.sufficient_funds_for_withdrawl(amount):
raise InsufficientFunds()
yield from log("{payer} has sufficient funds.", payer=payer)
payee.deposit(amount)
yield from log("{payee} received payment", payee=payee)
payer.withdraw(amount)
yield from log("{payer} made payment", payer=payer)
yield from server.update_balances([payer, payee])
Явный event loop
yield from asyncio.sleep(1.5, loop=loop)
yield from asyncio.wait_for(f(), 15, loop=loop)
fut = asyncio.Future(loop=loop)
reader, writer = yield from asyncio.open_connection("www.python.org", 80,
loop=loop)
Тесты
class MyTest(unittest.TestCase):
def setUp(self):
self.loop = asyncio.new_event_loop()
asyncio.set_event_loop(None)
def tearDown(self):
self.loop.close()
def test_feature(self):
@asyncio.coroutine
def go():
yielf from asyncio.sleep(1.5, loop=self.loop)
self.loop.run_until_complete(go())
Ожидание одноразового события
fut = Future()
@asyncio.coroutine
def wait():
yield from fut
def sinal():
fut.set_result(None)
Transport/Protocol — не для вас
class Proto:
def connection_made(self, transport):
self.transport = transport
def data_received(self, data):
self.transport.write(b'echo' + data)
def connection_lost(self, exc):
self.transport = None
Stream API
reader, writer = open_connection(host, port)
data yield from reader.read()
writer.write(data)
yield from writer.drain()
writer.close()
Синхронный код — в executor
def syncronous_dns(host, port):
return socket.getaddrinfo(host, port)
ret = yield from loop.run_in_executor(None, syncronous_dns, "www.python.org", 80)
Блокировки
with (yield from lock):
code()
Очереди
yield from queue.put(value)
yield from queue.get()
Процессы
proc = yield from asyncio.create_subprocess_shell(cmd, **kwds)
result = yield from proc.communicate(request)
yield from proc.wait()
proc.returncode
call_soon/call_later
loop.call_soon(func, 1, 2, 3)
loop.call_later(1.5, func, 1, 2, 3)
@asyncio.coroutine
def func():
f()
yield from sleep(1.5)
g()
Task/Future cancellation
task.cancel()
- grandfather
- father
- son
Таймауты
@asyncio.coroutine
def task():
resp = yield from aiohttp.request('GET', 'http://python.org')
body = yield from resp.read()
resp.close()
return body
try:
body = yield asyncio.wait_for(task(), 10.5)
except asyncio.TimeoutError:
handle_timeout()
Ждем нескольких событий
yield from asyncio.gather(f(), g(), h())
Магические методы
def __init__(self):
yield from self.meth()
def __getattr__(self, name):
return (yield from self.dispatch(name))
trollius
● yield From(f())
● Python 2
● Библиотеки
Резюме
Удобное API
TCP/UDP/Unix
сокеты, unix pipes,
процессы
Мало библиотек
Нет встроенного
HTTP
aiohttp — доделаем
aiopg — сделали
aioredis — создается
Вопросы?
andrew.svetlov@gmail.com

Contenu connexe

Tendances

Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門
lestrrat
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
clkao
 
Controlling Arduino With PHP
Controlling Arduino With PHPControlling Arduino With PHP
Controlling Arduino With PHP
Thomas Weinert
 
Trading with opensource tools, two years later
Trading with opensource tools, two years laterTrading with opensource tools, two years later
Trading with opensource tools, two years later
clkao
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
Iftekhar Eather
 
JavaSE7 Launch Event: Java7xGroovy
JavaSE7 Launch Event: Java7xGroovyJavaSE7 Launch Event: Java7xGroovy
JavaSE7 Launch Event: Java7xGroovy
Yasuharu Nakano
 
Asynchronous I/O in PHP
Asynchronous I/O in PHPAsynchronous I/O in PHP
Asynchronous I/O in PHP
Thomas Weinert
 
20 modules i haven't yet talked about
20 modules i haven't yet talked about20 modules i haven't yet talked about
20 modules i haven't yet talked about
Tatsuhiko Miyagawa
 

Tendances (20)

Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)
Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)
Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)
 
Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門
 
ZeroMQ: Messaging Made Simple
ZeroMQ: Messaging Made SimpleZeroMQ: Messaging Made Simple
ZeroMQ: Messaging Made Simple
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
 
Teaching Your Machine To Find Fraudsters
Teaching Your Machine To Find FraudstersTeaching Your Machine To Find Fraudsters
Teaching Your Machine To Find Fraudsters
 
Controlling Arduino With PHP
Controlling Arduino With PHPControlling Arduino With PHP
Controlling Arduino With PHP
 
dotCloud and go
dotCloud and godotCloud and go
dotCloud and go
 
Gun make
Gun makeGun make
Gun make
 
Trading with opensource tools, two years later
Trading with opensource tools, two years laterTrading with opensource tools, two years later
Trading with opensource tools, two years later
 
Python Yield
Python YieldPython Yield
Python Yield
 
Webrtc mojo
Webrtc mojoWebrtc mojo
Webrtc mojo
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
 
JavaSE7 Launch Event: Java7xGroovy
JavaSE7 Launch Event: Java7xGroovyJavaSE7 Launch Event: Java7xGroovy
JavaSE7 Launch Event: Java7xGroovy
 
nginx mod PSGI
nginx mod PSGInginx mod PSGI
nginx mod PSGI
 
Asynchronous I/O in PHP
Asynchronous I/O in PHPAsynchronous I/O in PHP
Asynchronous I/O in PHP
 
Redis & ZeroMQ: How to scale your application
Redis & ZeroMQ: How to scale your applicationRedis & ZeroMQ: How to scale your application
Redis & ZeroMQ: How to scale your application
 
Python Coroutines, Present and Future
Python Coroutines, Present and FuturePython Coroutines, Present and Future
Python Coroutines, Present and Future
 
20 modules i haven't yet talked about
20 modules i haven't yet talked about20 modules i haven't yet talked about
20 modules i haven't yet talked about
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongers
 
Melhorando sua API com DSLs
Melhorando sua API com DSLsMelhorando sua API com DSLs
Melhorando sua API com DSLs
 

En vedette

En vedette (20)

Import
ImportImport
Import
 
Py3k
Py3kPy3k
Py3k
 
Writing Open Source Library
Writing Open Source LibraryWriting Open Source Library
Writing Open Source Library
 
Разработка сетевых приложений с gevent
Разработка сетевых приложений с geventРазработка сетевых приложений с gevent
Разработка сетевых приложений с gevent
 
Introduction to asyncio
Introduction to asyncioIntroduction to asyncio
Introduction to asyncio
 
Интерфейсы в Python
Интерфейсы в PythonИнтерфейсы в Python
Интерфейсы в Python
 
Planning libuv v2
Planning libuv v2Planning libuv v2
Planning libuv v2
 
Trust No One
Trust No OneTrust No One
Trust No One
 
CDRTool: CDR mediation and rating engine for OpenSIPS
CDRTool: CDR mediation and rating engine for OpenSIPSCDRTool: CDR mediation and rating engine for OpenSIPS
CDRTool: CDR mediation and rating engine for OpenSIPS
 
The Future of the PBX
The Future of the PBXThe Future of the PBX
The Future of the PBX
 
Python, WebRTC and You (v2)
Python, WebRTC and You (v2)Python, WebRTC and You (v2)
Python, WebRTC and You (v2)
 
Building an Open Source VoIP Hardware Phone
Building an Open Source VoIP Hardware PhoneBuilding an Open Source VoIP Hardware Phone
Building an Open Source VoIP Hardware Phone
 
WebRTC enabling your OpenSIPS infrastructure
WebRTC enabling your OpenSIPS infrastructureWebRTC enabling your OpenSIPS infrastructure
WebRTC enabling your OpenSIPS infrastructure
 
libuv, NodeJS and everything in between
libuv, NodeJS and everything in betweenlibuv, NodeJS and everything in between
libuv, NodeJS and everything in between
 
From SIP to WebRTC and vice versa
From SIP to WebRTC and vice versaFrom SIP to WebRTC and vice versa
From SIP to WebRTC and vice versa
 
Proyecto Open Pi Phone
Proyecto Open Pi PhoneProyecto Open Pi Phone
Proyecto Open Pi Phone
 
SylkServer: State of the art RTC application server
SylkServer: State of the art RTC application serverSylkServer: State of the art RTC application server
SylkServer: State of the art RTC application server
 
Escalabilidad horizontal desde las trincheras
Escalabilidad horizontal desde las trincherasEscalabilidad horizontal desde las trincheras
Escalabilidad horizontal desde las trincheras
 
A deep dive into libuv
A deep dive into libuvA deep dive into libuv
A deep dive into libuv
 
libuv: cross platform asynchronous i/o
libuv: cross platform asynchronous i/olibuv: cross platform asynchronous i/o
libuv: cross platform asynchronous i/o
 

Similaire à Asyncio

Flask patterns
Flask patternsFlask patterns
Flask patterns
it-people
 
Gevent what's the point
Gevent what's the pointGevent what's the point
Gevent what's the point
seanmcq
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
Qiangning Hong
 

Similaire à Asyncio (20)

Flask patterns
Flask patternsFlask patterns
Flask patterns
 
Gevent what's the point
Gevent what's the pointGevent what's the point
Gevent what's the point
 
Pyramid REST
Pyramid RESTPyramid REST
Pyramid REST
 
Webscraping with asyncio
Webscraping with asyncioWebscraping with asyncio
Webscraping with asyncio
 
Using ngx_lua in UPYUN
Using ngx_lua in UPYUNUsing ngx_lua in UPYUN
Using ngx_lua in UPYUN
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.js
 
Advanced redux
Advanced reduxAdvanced redux
Advanced redux
 
Rntb20200805
Rntb20200805Rntb20200805
Rntb20200805
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethods
 
Programação Assíncrona com Asyncio
Programação Assíncrona com AsyncioProgramação Assíncrona com Asyncio
Programação Assíncrona com Asyncio
 
Reduxing like a pro
Reduxing like a proReduxing like a pro
Reduxing like a pro
 
Pl python python w postgre-sql
Pl python   python w postgre-sqlPl python   python w postgre-sql
Pl python python w postgre-sql
 
Denys Serhiienko "ASGI in depth"
Denys Serhiienko "ASGI in depth"Denys Serhiienko "ASGI in depth"
Denys Serhiienko "ASGI in depth"
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJS
 
Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)
 
Phoenix + Reactで 社内システムを 密かに作ってる
Phoenix + Reactで 社内システムを 密かに作ってるPhoenix + Reactで 社内システムを 密かに作ってる
Phoenix + Reactで 社内システムを 密かに作ってる
 
Implementing Comet using PHP
Implementing Comet using PHPImplementing Comet using PHP
Implementing Comet using PHP
 
ES6 Overview
ES6 OverviewES6 Overview
ES6 Overview
 
Job Queue in Golang
Job Queue in GolangJob Queue in Golang
Job Queue in Golang
 

Dernier

%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
chiefasafspells
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 

Dernier (20)

%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare
 

Asyncio

  • 2. О себе ● Python Core Developer ● Принимал участие в создании asyncio ● Соавтор нескольких библиотек на основе asyncio — aiohttp, aiozmq, aiopg ● Использую asyncio на работе
  • 3. yield from import asyncio @asyncio.coroutine def task(): resp = yield from aiohttp.request('GET', 'http://python.org') if resp.status == 200: body = yield from resp.read() print(body) resp.close() asyncio.get_event_loop().run_until_complete(task())
  • 4. Упрощенный yield from for i in EXPR: yield i i.send(val) i.throw(exc) i.close()
  • 5. Полный вариант yield from _i = iter(EXPR) try: _y = next(_i) except StopIteration as _e: _r = _e.value else: while 1: try: _s = yield _y except GeneratorExit as _e: try: _m = _i.close except AttributeError: pass else: _m() raise _e except BaseException as _e: _x = sys.exc_info() try: _m = _i.throw except AttributeError: raise _e else: try: _y = _m(*_x) except StopIteration as _e: _r = _e.value break else: try: if _s is None: _y = next(_i) else: _y = _i.send(_s) except StopIteration as _e: _r = _e.value break RESULT = _r
  • 6. yield против yield from ● программный стек ● неудобные stack trace ● неприятная отладка ● Медленней в 20 раз Всё ровно наоборот :)
  • 7. Stack trace @asyncio.coroutine def inner(): raise RuntimeError("Ooops!") @asyncio.coroutine def outer(): yield from inner() loop = asyncio.get_event_loop() loop.run_until_complete(outer()) Traceback (most recent call last): File "s.py", line 13, in <module> loop.run_until_complete(outer()) File ".../asyncio/base_events.py", line 208, in run_until_complete return future.result() File ".../asyncio/futures.py", line 243, in result raise self._exception File ".../asyncio/tasks.py", line 302, in _step result = next(coro) File "s.py", line 9, in outer yield from inner() File ".../asyncio/tasks.py", line 84, in coro res = func(*args, **kw) File "s.py", line 5, in inner raise RuntimeError("Ooops!") RuntimeError: Ooops!
  • 8. Debug режим @asyncio.coroutine def f(): asyncio.sleep(10) # missing yield from loop = asyncio.get_event_loop() loop.run_until_complete(f()) Переменная окружения PYTHONASYNCIODEBUG $ PYTHONASYNCIODEBUG=1 python3 d.py Coroutine 'sleep' defined at /usr/lib/python3.4/asyncio/tasks.py:542 was never yielded from
  • 9. Отладка def g(): ret = yield from f() ● next ● step
  • 10. Переключение контекста def transfer(amount, payer, payee, server): if not payer.sufficient_funds_for_withdrawl(amount): raise InsufficientFunds() log("{payer} has sufficient funds.", payer=payer) payee.deposit(amount) log("{payee} received payment", payee=payee) payer.withdraw(amount) log("{payer} made payment", payer=payer) server.update_balances([payer, payee])
  • 11. Переключение контекста 2 @coroutine def transfer(amount, payer, payee, server): if not payer.sufficient_funds_for_withdrawl(amount): raise InsufficientFunds() log("{payer} has sufficient funds.", payer=payer) payee.deposit(amount) log("{payee} received payment", payee=payee) payer.withdraw(amount) log("{payer} made payment", payer=payer) yield from server.update_balances([payer, payee])
  • 12. Переключение контекста 3 @coroutine def transfer(amount, payer, payee, server): if not payer.sufficient_funds_for_withdrawl(amount): raise InsufficientFunds() yield from log("{payer} has sufficient funds.", payer=payer) payee.deposit(amount) yield from log("{payee} received payment", payee=payee) payer.withdraw(amount) yield from log("{payer} made payment", payer=payer) yield from server.update_balances([payer, payee])
  • 13. Переключение контекста 4 @coroutine def transfer(amount, payer, payee, server): with (yield from payer.hold(amount): if not payer.sufficient_funds_for_withdrawl(amount): raise InsufficientFunds() yield from log("{payer} has sufficient funds.", payer=payer) payee.deposit(amount) yield from log("{payee} received payment", payee=payee) payer.withdraw(amount) yield from log("{payer} made payment", payer=payer) yield from server.update_balances([payer, payee])
  • 14. Явный event loop yield from asyncio.sleep(1.5, loop=loop) yield from asyncio.wait_for(f(), 15, loop=loop) fut = asyncio.Future(loop=loop) reader, writer = yield from asyncio.open_connection("www.python.org", 80, loop=loop)
  • 15. Тесты class MyTest(unittest.TestCase): def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) def tearDown(self): self.loop.close() def test_feature(self): @asyncio.coroutine def go(): yielf from asyncio.sleep(1.5, loop=self.loop) self.loop.run_until_complete(go())
  • 16. Ожидание одноразового события fut = Future() @asyncio.coroutine def wait(): yield from fut def sinal(): fut.set_result(None)
  • 17. Transport/Protocol — не для вас class Proto: def connection_made(self, transport): self.transport = transport def data_received(self, data): self.transport.write(b'echo' + data) def connection_lost(self, exc): self.transport = None
  • 18. Stream API reader, writer = open_connection(host, port) data yield from reader.read() writer.write(data) yield from writer.drain() writer.close()
  • 19. Синхронный код — в executor def syncronous_dns(host, port): return socket.getaddrinfo(host, port) ret = yield from loop.run_in_executor(None, syncronous_dns, "www.python.org", 80)
  • 22. Процессы proc = yield from asyncio.create_subprocess_shell(cmd, **kwds) result = yield from proc.communicate(request) yield from proc.wait() proc.returncode
  • 23. call_soon/call_later loop.call_soon(func, 1, 2, 3) loop.call_later(1.5, func, 1, 2, 3) @asyncio.coroutine def func(): f() yield from sleep(1.5) g()
  • 25. Таймауты @asyncio.coroutine def task(): resp = yield from aiohttp.request('GET', 'http://python.org') body = yield from resp.read() resp.close() return body try: body = yield asyncio.wait_for(task(), 10.5) except asyncio.TimeoutError: handle_timeout()
  • 26. Ждем нескольких событий yield from asyncio.gather(f(), g(), h())
  • 27. Магические методы def __init__(self): yield from self.meth() def __getattr__(self, name): return (yield from self.dispatch(name))
  • 28. trollius ● yield From(f()) ● Python 2 ● Библиотеки
  • 29. Резюме Удобное API TCP/UDP/Unix сокеты, unix pipes, процессы Мало библиотек Нет встроенного HTTP aiohttp — доделаем aiopg — сделали aioredis — создается