Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Eventlet, ZeroMQ, and You
Search
Andrew Godwin
October 22, 2011
Programming
840
6
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Eventlet, ZeroMQ, and You
A talk I gave at PyCon Ukraine 2011.
Andrew Godwin
October 22, 2011
More Decks by Andrew Godwin
See All by Andrew Godwin
Reconciling Everything
andrewgodwin
1
410
Django Through The Years
andrewgodwin
0
330
Writing Maintainable Software At Scale
andrewgodwin
0
540
A Newcomer's Guide To Airflow's Architecture
andrewgodwin
0
430
Async, Python, and the Future
andrewgodwin
2
760
How To Break Django: With Async
andrewgodwin
1
840
Taking Django's ORM Async
andrewgodwin
0
860
The Long Road To Asynchrony
andrewgodwin
0
780
The Scientist & The Engineer
andrewgodwin
1
870
Other Decks in Programming
See All in Programming
AIを上手に使っていこうとしたら越境せざるを得なくなった話 〜実践1年で見えた境界を越えなければならない理由と進め方〜 / Crossing borders with AI
tomoyakitaura
4
1.1k
AI Agent時代のリアーキテクチャ戦略と実践
hokaccha
6
3.1k
市販E-Readerを乗っ取れ 〜Embedded Swiftで電子ペーパーガジェットを制御する〜
trickart
0
140
信頼性の目標を誰も求めてない
shubox
0
500
型解析で実現する Go の言語内 DSL / Conference に Go! タイムテーブルの歩き方 for Gophers
mazrean
0
140
PHPプロジェクトの結合バランスを可視化する #php_night
kajitack
0
230
ハーネス設計入門 〜プロンプト、コンテキストの次〜
kinopeee
55
36k
Webプラットフォームで議論されているセキュリティ課題 / Security issues being discussed on Web Platforms
petamoriken
0
420
FastAPI の並行処理モデルを完全に理解する
hoto17296
9
3.9k
LoopHub - ローカルで動く GitHub で、AI と共同開発
jugyo
1
480
一参加者から『中の人』へ 〜全通PHPerがブースに立って学んだ、カンファレンスを100倍楽しむコツ〜
wp_daisuke
0
140
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
120
Featured
See All Featured
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
480
Abbi's Birthday
coloredviolet
3
9.9k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
540
Utilizing Notion as your number one productivity tool
mfonobong
4
580
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
2
3.8k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Leo the Paperboy
mayatellez
8
2.3k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.6k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
270
The SEO Collaboration Effect
kristinabergwall1
1
550
Transcript
Eventlet, ZeroMQ & You Andrew Godwin @andrewgodwin
Who am I? http://www.flickr.com/photos/maistora/3014414972
The Plan http://www.flickr.com/photos/snapsi42/2609025344/
Eventlet Asynchronous concurrency framework http://www.flickr.com/photos/pagedooley/2814895287/
import eventlet from eventlet.green import urllib2 urls = ['http://ep.io', 'http://t.co']
results = [] def fetch(url): results.append(urllib2.urlopen(url).read()) for url in urls: eventlet.spawn(fetch, url)
Cooperative Threading You have to yield control. http://www.flickr.com/photos/nickwheeleroz/3406931272/
import eventlet import time def thread1(): time.sleep(5) # Does not
yield print 'five seconds a' eventlet.spawn(thread1) time.sleep(5) # Does not yield print 'five seconds b'
import eventlet import time def thread1(): eventlet.sleep(5) print 'five seconds
a' eventlet.spawn(thread1) eventlet.sleep(5) print 'five seconds b'
Greening the World It's that or monkeypatching. http://www.flickr.com/photos/mightyboybrian/3457507731/
import urllib2 from eventlet.green import urllib2 import zmq from eventlet.green
import zmq import socket from eventlet.green import socket
Nice Primitives Not to mention less race conditions. http://www.flickr.com/photos/mightyboybrian/3457507731/
from eventlet.timeout import Timeout try: with Timeout(30): do_stuff() except Timeout:
abort_abort()
from eventlet.semaphore import Semaphore sem = Semaphore(1) with sem: use_resource()
from eventlet.queue import Queue q = Queue() def worker(): while
True: print q.get() def producer(): while True: eventlet.sleep(1) q.put('lol') eventlet.spawn(worker) eventlet.spawn(producer)
from eventlet import GreenPool from eventlet.pools import Pool conns =
Pool(create=make_db_connection) threads = GreenPool(10) def querier(id): with pool.item() as conn: conn.execute('... WHERE id = %s', [id]) pool.imap(querier, [1, 2, 3, 4, 5])
Experiences from production There's still race conditions and bad libraries.
http://www.flickr.com/photos/iamdabe/4931554963/
Case Study: Epio Loadbalancer Now at version three. http://www.flickr.com/photos/jasohill/118616905/
Version One: HAProxy + reloader Occasionally slow, occasionally didn't reload.
Version Two: Custom Integrated Worked alright, but leaked sockets.
Version Three: Fresh, Separate Codenamed ”Mantrid”
address = ('0.0.0.0', 80) family = socket.AF_INET sock = eventlet.listen(address,
family) eventlet.serve( sock, self.handle, concurrency = 10000, )
address = ('127.0.0.1', 8042) family = socket.AF_INET sock = eventlet.listen(address,
family) management_app = ManagementApp(self) wsgi.server( sock, management_app.handle, )
class Spin(Action): def handle(self, sock, read_data, path, headers): while True:
# Sleep first eventlet.sleep(self.check_interval) # Check for another action action = self.balancer.resolve_host(self.host) if not isinstance(action, Spin): return action.handle( sock, read_data, path, headers )
ZeroMQ I was too lazy to use an Ø. http://www.flickr.com/photos/andresrueda/2926348197/
Not a message queue More like 'better sockets'. http://www.flickr.com/photos/96dpi/3816391053/
REQ / REP PUB / SUB PUSH / PULL
from eventlet.green import zmq ctx = zmq.Context() sock = ctx.socket(zmq.REQ)
sock.connect('tcp://127.0.0.1:1234') sock.connect('tcp://127.0.0.1:4321') sock.send('hi there') print sock.recv()
from eventlet.green import zmq ctx = zmq.Context() sock = ctx.socket(zmq.REP)
sock.bind('tcp://0.0.0.0:1234') while True: message = sock.recv() sock.send('you said: %s' % message)
from eventlet.green import zmq ctx = zmq.Context() sock = ctx.socket(zmq.PUB)
sock.connect('tcp://127.0.0.1:1234') sock.send('Hello, world!')
from eventlet.green import zmq ctx = zmq.Context() sock = ctx.socket(zmq.SUB)
sock.bind('tcp://0.0.0.0:1234') while True: print sock.recv()
The restrictions It's not quite too good to be true.
http://www.flickr.com/photos/maistora/3237164755/
Advanced ZeroMQ & Eventlet When one greenthread is not enough
http://www.flickr.com/photos/maistora/3237164755/
sock = ctx.socket(zmq.REQ) sock.send('help me! you're my only hope!') try:
with Timeout(30): response = sock.recv() deal_with(response) except Timeout: cleanup()
@zmq_loop(zmq.XREP, 8000) def handle_request(string): eventlet.sleep(10) return string * 2
try: parts = sock.recv_multipart(flags=zmq.NOBLOCK) except zmq.ZMQError, e: if e.errno ==
zmq.EAGAIN: eventlet.sleep(0.1) continue else: raise identities = parts[:parts.index("")] def call(identities, data): result = func(self, data) sock.send_multipart(identities + ["", result]) eventlet.spawn_n(call, identities, parts[-1])
Case Study: Epio Logging We really, really like data http://www.flickr.com/photos/jasohill/118616905/
Logging clients They're the things that make logs
Logging servers They're the things that save and store logs
# Servers zmq.PULL -> Recieves logs zmq.REP -> Lets website
query for log data # Clients zmq.PUSH -> Sends logs, connected to all servers
Conclusions Where Andrew waffles for a bit. http://www.flickr.com/photos/oimax/108058706/
Thanks. Andrew Godwin @andrewgodwin http://aeracode.org