SlideShare a Scribd company logo
HOW TO DEAL WITH
BLOCKING CODE WITHIN
ASYNCIO EVENT LOOP
Nikolay Novik
http://github.com/jettify
I AM ...
Software Engineer: at DataRobot Ukraine
Github:
My Projects:
database clients:
aiomysql, aioobc, aiogibson
web and etc:
aiohttp_debugtoolbar, aiobotocore,
aiohttp_mako, aiohttp_sse, aiogearman,
aiomysql_replicatoin
http://github.com/jettify
POLL
YOU AND ASYNCIO:
1. I am using asyncio extensively
2. I am using Twisted, Tornado, gevent etc. extensively
3. I think async programming is kinda cool
ASYNCIO
The asyncio project was officially launched with the release
of Python 3.4 in March 2014.
Bare: almost no library
One year later, asyncio has a strong community writing
libraries on top of it.
But what to do when available libraries work in sync way,
potentially blocking event loop?
RULES OF ASYNC CLUB
RULE #1
You do not block event loop
RULE #2
You never block event loop
BLOCKING CALLS IN THIRD PARTY
LIBRARIES
Network IO
API wrappers
Database clients
Message queues
FileSystem IO
CPU
Set environment variable
DEBUGGING BLOCKING CALLS TIP
PYTHONASYNCIODEBUG=1
import asyncio
import time
loop = asyncio.get_event_loop()
loop.slow_callback_duration = 0.01
async def sleeper():
time.sleep(0.1) # we block here
loop.run_until_complete(sleeper())
Executing <Task finished coro=<sleeper() done, defined at
code/debug_example.py:9> result=None created at
/usr/local/lib/python3.5/asyncio/base_events.py:323>
took 0.102 seconds
APPROACH #1 IS THERE ANY
SUITABLE LIBRARY?
Search asyncio compatible library on:
1. google ~ 98k results
2. pypi ~200 packages
3. asyncio wiki page:
4. aio-libs:
https://github.com/python/asyncio/wiki/ThirdParty
https://github.com/aio-libs
Read the (f*g) source code of your libraries! Example of
python code from OneDrive SDK
Most of the time you want to do HTTP requests using event
loop not thread pool.
THIRD PARTY LIBRARIES PRO TIP
@asyncio.coroutine
def get_async(self):
"""Sends the GET request using an asyncio coroutine
....
"""
future = self._client._loop.run_in_executor(None,
self.get)
collection_response = yield from future
return collection_response
Most hipsters databases use REST API as primary access
method:
Easy to implement required subset of APIs.
APPROACH #2 IS REST API AVAILABLE?
DynamoDB
Neo4j
Elasticsearch
HBase
HDFS
CouchDB
Riak
VoltDB
InfluxDB
ArangoDB
is your friend
Connection pooling helps to save on expensive connection
creation. (PS: checkout new aiohttp 0.18.x release)
REST CLIENT TIP
aiohttp.ClientSession
import asyncio
import aiohttp
# carry the loop Luke!
loop = asyncio.get_event_loop()
async def go():
session = aiohttp.ClientSession(loop=loop)
async with session.get('http://python.org') as resp:
data = await resp.text()
print(data)
session.close()
loop.run_until_complete(go())
APPROACH #3 IS THERE SIMPLE TEXT
OR BINARY PROTOCOL?
Example of databases and message queues with binary
protocol:
redis
memcached
couchebase
grearman
beanstalkd
disque
Do not afraid to get your hands dirty.
Example: Simple binary protocol implementation
Simple but no protocol pipelining.
import asyncio, struct
from aiogibson import encode_command
async def read_from_connection(host, port, *, loop=None):
reader, writer = await asyncio.open_connection(
host, port, loop=loop)
cmd = encode_command(b'GET', 'key')
writer.write(cmd)
header = await reader.readexactly(4 + 2 + 1)
unpacked = struct.unpack(b'<HBI', header)
code, gb_encoding, resp_size = unpacked
payload = await reader.readexactly(resp_size)
print(payload)
Most binary protocols support pipelining
More info: http://tailhook.github.io/request-pipelining-
presentation/ presentation/index.html
PROTOCOL PIPELINING
Example: Simple pipelined binary protocol implementation
See for reference implementation.
def execute(self):
cmd = encode_command(b'GET', 'key')
self.writer.write(cmd)
fut = asyncio.Future(loop=self._loop)
self._queue.append(fut)
return fut
async def reader_task(self):
while True:
header = await self.reader.readexactly(4 + 2 + 1)
unpacked = struct.unpack(b'<HBI', header)
code, gb_encoding, resp_size = unpacked
# wait and read payload
payload = await reader.readexactly(resp_size)
future = self._queue.pop()
future.set_result(payload)
aioredis
In good sync database clients IO decoupled from protocol
parsers why not just rewrite IO part?
APPROACH #4 IS SYNC PYTHON CLIENT
AVAILABLE?
1. Locate socket.recv()
2. Replace with await reader.read()
3. Make function coroutine with async def
4. Call this function with await
5. Call parent functions with await
Yes. Make every blocking call in separate thread
APPROACH #5 IS THERE UNIVERSAL
SOLUTION TO ALL PROBLEMS?
import asyncio
from pyodbc import connect
loop = asyncio.get_event_loop()
executor = ThreadPoolExecutor(max_workers=4)
async def test_example():
dsn = 'Driver=SQLite;Database=sqlite.db'
conn = await loop.run_in_executor(executor, connect, dsn)
cursor = await loop.run_in_executor(executor, conn.cursor)
conn = await loop.run_in_executor(executor, cursor.execute,
'SELECT 42;')
loop.run_until_complete(test_example())
For python code
For Cython
BUT HOW I KNOW WHICH METHOD TO
CALL IN THREAD?
requests.get()
with nogil:
[code to be executed with the GIL released]
For C extension
Py_BEGIN_ALLOW_THREADS
ret = SQLDriverConnect(hdbc, 0, szConnect, SQL_NTS,
0, 0, 0, SQL_DRIVER_NOPROMPT);
Py_END_ALLOW_THREADS
Only good way to use files asynchronously by using thread
pools.
WHAT ABOUT FILESYSTEM IO?
asyncio does not support asynchronous operations on the
filesystem due to OS limitations.
On background uses ThreadPoolExecutor for
blocking calls.
aiofiles library workaround
async def go():
f = await aiofiles.open('filename', mode='r')
try:
data = await f.read()
finally:
await f.close()
print(data)
loop.run_until_complete(go())
aiofiles
WHAT ABOUT CPU INTENSIVE TASK?
loop = asyncio.get_event_loop()
executor = ProcessPoolExecutor(max_workers=3)
def is_prime(n):
if n % 2 == 0: return False
sqrt_n = int(math.floor(math.sqrt(n)))
for i in range(3, sqrt_n + 1, 2):
if n % i == 0: return False
return True
async def go():
n = 112272535095293
result = await loop.run_in_executor(executor, is_prime, n)
loop.run_until_complete(go(loop, executor))
THANKS!
Ad

Recommended

PPTX
Vinyl floor finishes
Nur Azreen
 
PDF
اعمال المبانى
Osama Tarek
 
PPTX
Presentation chair
Maryam Shah
 
PDF
BUILDING APPS WITH ASYNCIO
Mykola Novik
 
PDF
Introduction to Python Asyncio
Nathan Van Gheem
 
PDF
Original slides from Ryan Dahl's NodeJs intro talk
Aarti Parikh
 
KEY
Plack perl superglue for web frameworks and servers
Tatsuhiko Miyagawa
 
ODP
Building serverless application on the Apache Openwhisk platform
Lucio Grenzi
 
ODP
Lucio Grenzi - Building serverless applications on the Apache OpenWhisk platf...
Codemotion
 
PDF
Syncing up with Python’s asyncio for (micro) service development, Joir-dan Gumbs
Pôle Systematic Paris-Region
 
KEY
node.js: Javascript's in your backend
David Padbury
 
PDF
Release with confidence
John Congdon
 
PDF
MongoDB World 2018: Tutorial - Got Dibs? Building a Real-Time Bidding App wit...
MongoDB
 
PPTX
Async programming and python
Chetan Giridhar
 
PDF
Logging for Production Systems in The Container Era
Sadayuki Furuhashi
 
PDF
HTML5 tutorial: canvas, offfline & sockets
Remy Sharp
 
PPTX
PHP on Heroku: Deploying and Scaling Apps in the Cloud
Salesforce Developers
 
PPTX
Node Session - 1
Bhavin Shah
 
PDF
Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)
Fabrice Bernhard
 
PPT
Exploring Node.jS
Deepu S Nath
 
PDF
Why scala is not my ideal language and what I can do with this
Ruslan Shevchenko
 
PPTX
Proposal
Constantine Priemski
 
PPTX
Everything you wanted to know about writing async, concurrent http apps in java
Baruch Sadogursky
 
PDF
TIAD - DYI: A simple orchestrator built step by step
The Incredible Automation Day
 
PDF
Software Quality Assurance Tooling 2023
Henry Schreiner
 
PDF
Software Quality Assurance Tooling - Wintersession 2024
Henry Schreiner
 
PDF
How to create multiprocess server on windows with ruby - rubykaigi2016 Ritta ...
Ritta Narita
 
PDF
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
jeffz
 
PDF
Why Edge Computing Matters in Mobile Application Tech.pdf
IMG Global Infotech
 
PDF
Introduction to Agile Frameworks for Product Managers.pdf
Ali Vahed
 

More Related Content

Similar to HOW TO DEAL WITH BLOCKING CODE WITHIN ASYNCIO EVENT LOOP (20)

ODP
Lucio Grenzi - Building serverless applications on the Apache OpenWhisk platf...
Codemotion
 
PDF
Syncing up with Python’s asyncio for (micro) service development, Joir-dan Gumbs
Pôle Systematic Paris-Region
 
KEY
node.js: Javascript's in your backend
David Padbury
 
PDF
Release with confidence
John Congdon
 
PDF
MongoDB World 2018: Tutorial - Got Dibs? Building a Real-Time Bidding App wit...
MongoDB
 
PPTX
Async programming and python
Chetan Giridhar
 
PDF
Logging for Production Systems in The Container Era
Sadayuki Furuhashi
 
PDF
HTML5 tutorial: canvas, offfline & sockets
Remy Sharp
 
PPTX
PHP on Heroku: Deploying and Scaling Apps in the Cloud
Salesforce Developers
 
PPTX
Node Session - 1
Bhavin Shah
 
PDF
Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)
Fabrice Bernhard
 
PPT
Exploring Node.jS
Deepu S Nath
 
PDF
Why scala is not my ideal language and what I can do with this
Ruslan Shevchenko
 
PPTX
Proposal
Constantine Priemski
 
PPTX
Everything you wanted to know about writing async, concurrent http apps in java
Baruch Sadogursky
 
PDF
TIAD - DYI: A simple orchestrator built step by step
The Incredible Automation Day
 
PDF
Software Quality Assurance Tooling 2023
Henry Schreiner
 
PDF
Software Quality Assurance Tooling - Wintersession 2024
Henry Schreiner
 
PDF
How to create multiprocess server on windows with ruby - rubykaigi2016 Ritta ...
Ritta Narita
 
PDF
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
jeffz
 
Lucio Grenzi - Building serverless applications on the Apache OpenWhisk platf...
Codemotion
 
Syncing up with Python’s asyncio for (micro) service development, Joir-dan Gumbs
Pôle Systematic Paris-Region
 
node.js: Javascript's in your backend
David Padbury
 
Release with confidence
John Congdon
 
MongoDB World 2018: Tutorial - Got Dibs? Building a Real-Time Bidding App wit...
MongoDB
 
Async programming and python
Chetan Giridhar
 
Logging for Production Systems in The Container Era
Sadayuki Furuhashi
 
HTML5 tutorial: canvas, offfline & sockets
Remy Sharp
 
PHP on Heroku: Deploying and Scaling Apps in the Cloud
Salesforce Developers
 
Node Session - 1
Bhavin Shah
 
Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)
Fabrice Bernhard
 
Exploring Node.jS
Deepu S Nath
 
Why scala is not my ideal language and what I can do with this
Ruslan Shevchenko
 
Everything you wanted to know about writing async, concurrent http apps in java
Baruch Sadogursky
 
TIAD - DYI: A simple orchestrator built step by step
The Incredible Automation Day
 
Software Quality Assurance Tooling 2023
Henry Schreiner
 
Software Quality Assurance Tooling - Wintersession 2024
Henry Schreiner
 
How to create multiprocess server on windows with ruby - rubykaigi2016 Ritta ...
Ritta Narita
 
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
jeffz
 

Recently uploaded (20)

PDF
Why Edge Computing Matters in Mobile Application Tech.pdf
IMG Global Infotech
 
PDF
Introduction to Agile Frameworks for Product Managers.pdf
Ali Vahed
 
PPTX
IObit Driver Booster Pro 12 Crack Latest Version Download
pcprocore
 
PPTX
HYBRIDIZATION OF ALKANES AND ALKENES ...
karishmaduhijod1
 
PDF
OpenChain Webinar - AboutCode - Practical Compliance in One Stack – Licensing...
Shane Coughlan
 
DOCX
Best AI-Powered Wearable Tech for Remote Health Monitoring in 2025
SEOLIFT - SEO Company London
 
PDF
Sysinfo OST to PST Converter Infographic
SysInfo Tools
 
PDF
Which Hiring Management Tools Offer the Best ROI?
HireME
 
PPT
Complete Guideliness to Build an Effective Maintenance Plan.ppt
QualityzeInc1
 
PDF
Decipher SEO Solutions for your startup needs.
mathai2
 
PDF
Why Every Growing Business Needs a Staff Augmentation Company IN USA.pdf
mary rojas
 
PPTX
Foundations of Marketo Engage - Programs, Campaigns & Beyond - June 2025
BradBedford3
 
PDF
Azure AI Foundry: The AI app and agent factory
Maxim Salnikov
 
PPTX
AI for PV: Development and Governance for a Regulated Industry
Biologit
 
DOCX
Zoho Creator Solution for EI by Elsner Technologies.docx
Elsner Technologies Pvt. Ltd.
 
PDF
Simplify Task, Team, and Project Management with Orangescrum Work
Orangescrum
 
PDF
CodeCleaner: Mitigating Data Contamination for LLM Benchmarking
arabelatso
 
PDF
Modern Platform Engineering with Choreo - The AI-Native Internal Developer Pl...
WSO2
 
PPTX
Top Time Tracking Solutions for Accountants
oliviareed320
 
PPTX
Advance Doctor Appointment Booking App With Online Payment
AxisTechnolabs
 
Why Edge Computing Matters in Mobile Application Tech.pdf
IMG Global Infotech
 
Introduction to Agile Frameworks for Product Managers.pdf
Ali Vahed
 
IObit Driver Booster Pro 12 Crack Latest Version Download
pcprocore
 
HYBRIDIZATION OF ALKANES AND ALKENES ...
karishmaduhijod1
 
OpenChain Webinar - AboutCode - Practical Compliance in One Stack – Licensing...
Shane Coughlan
 
Best AI-Powered Wearable Tech for Remote Health Monitoring in 2025
SEOLIFT - SEO Company London
 
Sysinfo OST to PST Converter Infographic
SysInfo Tools
 
Which Hiring Management Tools Offer the Best ROI?
HireME
 
Complete Guideliness to Build an Effective Maintenance Plan.ppt
QualityzeInc1
 
Decipher SEO Solutions for your startup needs.
mathai2
 
Why Every Growing Business Needs a Staff Augmentation Company IN USA.pdf
mary rojas
 
Foundations of Marketo Engage - Programs, Campaigns & Beyond - June 2025
BradBedford3
 
Azure AI Foundry: The AI app and agent factory
Maxim Salnikov
 
AI for PV: Development and Governance for a Regulated Industry
Biologit
 
Zoho Creator Solution for EI by Elsner Technologies.docx
Elsner Technologies Pvt. Ltd.
 
Simplify Task, Team, and Project Management with Orangescrum Work
Orangescrum
 
CodeCleaner: Mitigating Data Contamination for LLM Benchmarking
arabelatso
 
Modern Platform Engineering with Choreo - The AI-Native Internal Developer Pl...
WSO2
 
Top Time Tracking Solutions for Accountants
oliviareed320
 
Advance Doctor Appointment Booking App With Online Payment
AxisTechnolabs
 
Ad

HOW TO DEAL WITH BLOCKING CODE WITHIN ASYNCIO EVENT LOOP

  • 1. HOW TO DEAL WITH BLOCKING CODE WITHIN ASYNCIO EVENT LOOP Nikolay Novik http://github.com/jettify
  • 2. I AM ... Software Engineer: at DataRobot Ukraine Github: My Projects: database clients: aiomysql, aioobc, aiogibson web and etc: aiohttp_debugtoolbar, aiobotocore, aiohttp_mako, aiohttp_sse, aiogearman, aiomysql_replicatoin http://github.com/jettify
  • 3. POLL YOU AND ASYNCIO: 1. I am using asyncio extensively 2. I am using Twisted, Tornado, gevent etc. extensively 3. I think async programming is kinda cool
  • 4. ASYNCIO The asyncio project was officially launched with the release of Python 3.4 in March 2014. Bare: almost no library One year later, asyncio has a strong community writing libraries on top of it. But what to do when available libraries work in sync way, potentially blocking event loop?
  • 5. RULES OF ASYNC CLUB RULE #1 You do not block event loop RULE #2 You never block event loop
  • 6. BLOCKING CALLS IN THIRD PARTY LIBRARIES Network IO API wrappers Database clients Message queues FileSystem IO CPU
  • 7. Set environment variable DEBUGGING BLOCKING CALLS TIP PYTHONASYNCIODEBUG=1 import asyncio import time loop = asyncio.get_event_loop() loop.slow_callback_duration = 0.01 async def sleeper(): time.sleep(0.1) # we block here loop.run_until_complete(sleeper()) Executing <Task finished coro=<sleeper() done, defined at code/debug_example.py:9> result=None created at /usr/local/lib/python3.5/asyncio/base_events.py:323> took 0.102 seconds
  • 8. APPROACH #1 IS THERE ANY SUITABLE LIBRARY? Search asyncio compatible library on: 1. google ~ 98k results 2. pypi ~200 packages 3. asyncio wiki page: 4. aio-libs: https://github.com/python/asyncio/wiki/ThirdParty https://github.com/aio-libs
  • 9. Read the (f*g) source code of your libraries! Example of python code from OneDrive SDK Most of the time you want to do HTTP requests using event loop not thread pool. THIRD PARTY LIBRARIES PRO TIP @asyncio.coroutine def get_async(self): """Sends the GET request using an asyncio coroutine .... """ future = self._client._loop.run_in_executor(None, self.get) collection_response = yield from future return collection_response
  • 10. Most hipsters databases use REST API as primary access method: Easy to implement required subset of APIs. APPROACH #2 IS REST API AVAILABLE? DynamoDB Neo4j Elasticsearch HBase HDFS CouchDB Riak VoltDB InfluxDB ArangoDB
  • 11. is your friend Connection pooling helps to save on expensive connection creation. (PS: checkout new aiohttp 0.18.x release) REST CLIENT TIP aiohttp.ClientSession import asyncio import aiohttp # carry the loop Luke! loop = asyncio.get_event_loop() async def go(): session = aiohttp.ClientSession(loop=loop) async with session.get('http://python.org') as resp: data = await resp.text() print(data) session.close() loop.run_until_complete(go())
  • 12. APPROACH #3 IS THERE SIMPLE TEXT OR BINARY PROTOCOL? Example of databases and message queues with binary protocol: redis memcached couchebase grearman beanstalkd disque Do not afraid to get your hands dirty.
  • 13. Example: Simple binary protocol implementation Simple but no protocol pipelining. import asyncio, struct from aiogibson import encode_command async def read_from_connection(host, port, *, loop=None): reader, writer = await asyncio.open_connection( host, port, loop=loop) cmd = encode_command(b'GET', 'key') writer.write(cmd) header = await reader.readexactly(4 + 2 + 1) unpacked = struct.unpack(b'<HBI', header) code, gb_encoding, resp_size = unpacked payload = await reader.readexactly(resp_size) print(payload)
  • 14. Most binary protocols support pipelining More info: http://tailhook.github.io/request-pipelining- presentation/ presentation/index.html PROTOCOL PIPELINING
  • 15. Example: Simple pipelined binary protocol implementation See for reference implementation. def execute(self): cmd = encode_command(b'GET', 'key') self.writer.write(cmd) fut = asyncio.Future(loop=self._loop) self._queue.append(fut) return fut async def reader_task(self): while True: header = await self.reader.readexactly(4 + 2 + 1) unpacked = struct.unpack(b'<HBI', header) code, gb_encoding, resp_size = unpacked # wait and read payload payload = await reader.readexactly(resp_size) future = self._queue.pop() future.set_result(payload) aioredis
  • 16. In good sync database clients IO decoupled from protocol parsers why not just rewrite IO part? APPROACH #4 IS SYNC PYTHON CLIENT AVAILABLE? 1. Locate socket.recv() 2. Replace with await reader.read() 3. Make function coroutine with async def 4. Call this function with await 5. Call parent functions with await
  • 17. Yes. Make every blocking call in separate thread APPROACH #5 IS THERE UNIVERSAL SOLUTION TO ALL PROBLEMS? import asyncio from pyodbc import connect loop = asyncio.get_event_loop() executor = ThreadPoolExecutor(max_workers=4) async def test_example(): dsn = 'Driver=SQLite;Database=sqlite.db' conn = await loop.run_in_executor(executor, connect, dsn) cursor = await loop.run_in_executor(executor, conn.cursor) conn = await loop.run_in_executor(executor, cursor.execute, 'SELECT 42;') loop.run_until_complete(test_example())
  • 18. For python code For Cython BUT HOW I KNOW WHICH METHOD TO CALL IN THREAD? requests.get() with nogil: [code to be executed with the GIL released] For C extension Py_BEGIN_ALLOW_THREADS ret = SQLDriverConnect(hdbc, 0, szConnect, SQL_NTS, 0, 0, 0, SQL_DRIVER_NOPROMPT); Py_END_ALLOW_THREADS
  • 19. Only good way to use files asynchronously by using thread pools. WHAT ABOUT FILESYSTEM IO? asyncio does not support asynchronous operations on the filesystem due to OS limitations.
  • 20. On background uses ThreadPoolExecutor for blocking calls. aiofiles library workaround async def go(): f = await aiofiles.open('filename', mode='r') try: data = await f.read() finally: await f.close() print(data) loop.run_until_complete(go()) aiofiles
  • 21. WHAT ABOUT CPU INTENSIVE TASK? loop = asyncio.get_event_loop() executor = ProcessPoolExecutor(max_workers=3) def is_prime(n): if n % 2 == 0: return False sqrt_n = int(math.floor(math.sqrt(n))) for i in range(3, sqrt_n + 1, 2): if n % i == 0: return False return True async def go(): n = 112272535095293 result = await loop.run_in_executor(executor, is_prime, n) loop.run_until_complete(go(loop, executor))