Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Cooperative Multitasking with Twisted: Getting ...
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
David Reid
February 01, 2012
Programming
810
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Cooperative Multitasking with Twisted: Getting Things Done Concurrently
David Reid
February 01, 2012
Other Decks in Programming
See All in Programming
ユニットテストの先へ:テスト技法で要求・仕様を整理するJava開発実践 / Beyond_Unit_Testing_Practical_Java_Development_Techniques_for_Organizing_Requirements_and_Specifications
shimashima35
0
410
OSもどきOS
arkw
0
580
Javaの型とAI時代に型が大事な理由 / java types and type in AI era
kishida
2
140
AI時代のUIはどこへ行く?その2!
yusukebe
22
7.4k
TypeScript+Orvalで実現する型安全かつ堅牢でスケーラブルなマルチチャネル通知基盤 / TSKaigi Night talks ~after conference~
d0riven
0
350
Contextとはなにか
chiroruxx
1
340
New "Type" system on PicoRuby
pocke
1
980
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
170
ECSアプリログをFireLensでコスト削減しようとしたけど諦めた話 in Fargate×Node.js
akihisaikeda
2
4.2k
なぜ型を書くのか? TSKaigi2026で改めて考える #tskaigi_smarthr
kajitack
0
100
Vite+ Unified Toolchain for the Web
naokihaba
0
320
気圧・高度・GPSを記録&可視化するアプリ「Koudo」を作った話
hjmkth
1
310
Featured
See All Featured
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.2k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
55k
Making Projects Easy
brettharned
120
6.7k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
540
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.7k
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.9k
Prompt Engineering for Job Search
mfonobong
0
350
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
160
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
320
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
290
Transcript
Cooperative Multitasking with Twisted “Getting Things Done Concurrently” David Reid
<
[email protected]
>
Alternate Title
Alternate Title How I learned to stop worrying (about threads)
and use timed events to yield to the reactor so that synchronous tasks can cooperate with each other in a single thread.
Cooperative Multitasking
Cooperative Multitasking
Cooperative Multitasking
Cooperative Multitasking
Cooperative Multitasking
Cooperative Multitasking
Things will block
Fine in moderation
So what blocks?
Non-twisted networking
Non-twisted networking urllib & httplib smtplib python-memcached
Non-twisted networking twisted.web.client twisted.mail.smtp twisted.protocols.memcache
C Extensions
C Extensions DB-APIs: psycopg2, sqlite Hard math: PyCrypto socket.gethostbyname
C Extensions twisted.enterprise deferToThread deferToThread/twisted.names
File I/O
File I/O Yeah ... pretty much all of it.
The for loop.
def do_stuff(data): for x in data: do_work(x)
def do_stuff(data): for x in data: do_work(x)
Next: Introducing Twisted in 3 slides.
while true: stuff = wait_for_stuff(timeout) if stuff: check_reads_and_writes() run_timed_events() The
Reactor: Approximately
while true: stuff = wait_for_stuff(timeout) if stuff: check_reads_and_writes() run_timed_events() The
Reactor: Approximately
while true: stuff = wait_for_stuff(timeout) if stuff: check_reads_and_writes() run_timed_events() The
Reactor: Approximately
while true: stuff = wait_for_stuff(timeout) if stuff: check_reads_and_writes() run_timed_events() The
Reactor: Approximately
Deferreds Data Source result or failure Deferred
Deferreds Data Source result or failure Deferred res
Deferreds Data Source result or failure Deferred err
Deferreds Data Source result or failure Deferred
Deferreds Data Source result or failure Deferred err
Deferreds Data Source result or failure Deferred res
reactor.callLater
reactor.callLater reactor.callLater(10, do_stuff)
reactor.callLater reactor.callLater(0.001, do_stuff)
def do_stuff(data): d = Deferred() def do_later(): do_work(data.pop()) if not
data: d.callback(True) else: reactor.callLater(0.1, do_later) reactor.callLater(0.1, do_later) return d
def do_stuff(data): d = Deferred() def do_later(): do_work(data.pop()) if not
data: d.callback(True) else: reactor.callLater(0.1, do_later) reactor.callLater(0.1, do_later) return d
def do_stuff(data): d = Deferred() def do_later(): do_work(data.pop()) if not
data: d.callback(True) else: reactor.callLater(0.1, do_later) reactor.callLater(0.1, do_later) return d
def do_stuff(data): d = Deferred() def do_later(): do_work(data.pop()) if not
data: d.callback(True) else: reactor.callLater(0.1, do_later) reactor.callLater(0.1, do_later) return d
def do_stuff(data): d = Deferred() def do_later(): do_work(data.pop()) if not
data: d.callback(True) else: reactor.callLater(0.1, do_later) reactor.callLater(0.1, do_later) return d
def do_stuff(data): d = Deferred() def do_later(): do_work(data.pop()) if not
data: d.callback(True) else: reactor.callLater(0.1, do_later) reactor.callLater(0.1, do_later) return d
def do_stuff(data): d = Deferred() def do_later(): do_work(data.pop()) if not
data: d.callback(True) else: reactor.callLater(0.1, do_later) reactor.callLater(0.1, do_later) return d
def do_stuff(data): d = Deferred() def do_later(): do_work(data.pop()) if not
data: d.callback(True) else: reactor.callLater(0.1, do_later) reactor.callLater(0.1, do_later) return d
twisted.internet.task.Cooperator
twisted.internet.task.Cooperator twisted.internet.task.coiterate
twisted.internet.task.Cooperator twisted.internet.task.coiterate twisted.internet.task.cooperate
def do_stuff(data): def doterator(): for x in data: do_work(x) yield
None return coiterate(doterator())
def do_stuff(data): def doterator(): for x in data: do_work(x) yield
None return coiterate(doterator())
def do_stuff(data): def doterator(): for x in data: do_work(x) yield
None return coiterate(doterator())
def do_stuff(data): def doterator(): for x in data: do_work(x) yield
None return coiterate(doterator())
def do_stuff(data): def doterator(): for x in data: do_work(x) yield
None return coiterate(doterator())
• Similar to coiterate • Returns a CooperativeTask instead of
a Deferred cooperate
def do_stuff(data): def doterator(): for x in data: do_work(x) yield
None return cooperate(doterator())
def do_stuff(data): def doterator(): for x in data: do_work(x) yield
None return cooperate(doterator())
def do_stuff(data): def doterator(): for x in data: do_work(x) yield
None return cooperate(doterator())
def do_stuff(data): def doterator(): for x in data: do_work(x) yield
None return cooperate(doterator())
def do_stuff(data): def doterator(): for x in data: do_work(x) yield
None return cooperate(doterator()) task = do_stuff(someData) task_d = task.whenDone() task.pause() task.resume() task.stop()
def do_stuff(data): def doterator(): for x in data: do_work(x) yield
None return cooperate(doterator()) task = do_stuff(someData) task_d = task.whenDone() task.pause() task.resume() task.stop()
def do_stuff(data): def doterator(): for x in data: do_work(x) yield
None return cooperate(doterator()) task = do_stuff(someData) task_d = task.whenDone() task.pause() task.resume() task.stop()
def do_stuff(data): def doterator(): for x in data: do_work(x) yield
None return cooperate(doterator()) task = do_stuff(someData) task_d = task.whenDone() task.pause() task.resume() task.stop()
def do_stuff(data): def doterator(): for x in data: do_work(x) yield
None return cooperate(doterator()) task = do_stuff(someData) task_d = task.whenDone() task.pause() task.resume() task.stop()
def do_stuff(data): def doterator(): for x in data: do_work(x) yield
None return cooperate(doterator()) task = do_stuff(someData) task_d = task.whenDone() task.pause() task.resume() task.stop()
def do_stuff(data): def doterator(): for x in data: do_work(x) yield
None return cooperate(doterator()) task = do_stuff(someData) task_d = task.whenDone() task.pause() task.resume() task.stop()
• Your code is going to block. • Iterating over
stuff is a big place where synchronous code blocks for unacceptable periods of time. • Iterating is easily broken up by timed events. • Twisted comes with APIs for making this easy. • These APIs are the building blocks for your ideal task system.
Questions (Mine, not yours.)
Why?
Why? Being able to do more stuff is sometimes more
important than doing stuff quickly. * * Making a single user’s request 10ms faster is great, but not if you can only handle 1 request at a time.
Why call later instead of next iteration?
Why call later instead of next iteration? Timed events are
more flexible and you need them anyway.
Can’t I just use deferToThread for python code?
Can’t I just use deferToThread for python code? Yes, but
the GIL hates you.
Can’t I just use deferToThread for python code? Yes, but
the GIL hates you. It’s OK, it hates me too.
Can’t I just run code in a separate processes?
Can’t I just run code in a separate processes? Yes,
look at Ampoule.
Can’t I just run code in a separate processes? Yes,
look at Ampoule. But you probably want those processes to do more than one thing too.
This isn’t appropriate for my situation at all.
This isn’t appropriate for my situation at all. So don’t
do it.
This isn’t appropriate for my situation at all. So don’t
do it. Seriously.
SERIOUSLY.
• Twisted (http://twistedmatrix.com) • Ampoule (https://launchpad.net/ampoule) • txRDQ (https://launchpad.net/txrdq) •
Mochi Media (WE’RE HIRING) • http://mochimedia.com • http://bit.ly/mochi-jobs References