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
Django and this thing called Channels
Search
Andrew Godwin
March 09, 2016
Programming
1
620
Django and this thing called Channels
A talk I gave at Python SF Meetup, March 2016.
Andrew Godwin
March 09, 2016
Tweet
Share
More Decks by Andrew Godwin
See All by Andrew Godwin
Reconciling Everything
andrewgodwin
1
230
Django Through The Years
andrewgodwin
0
110
Writing Maintainable Software At Scale
andrewgodwin
0
350
A Newcomer's Guide To Airflow's Architecture
andrewgodwin
0
270
Async, Python, and the Future
andrewgodwin
2
560
How To Break Django: With Async
andrewgodwin
1
610
Taking Django's ORM Async
andrewgodwin
0
620
The Long Road To Asynchrony
andrewgodwin
0
540
The Scientist & The Engineer
andrewgodwin
1
630
Other Decks in Programming
See All in Programming
CSC307 Lecture 11
javiergs
PRO
0
240
【Go言語】golangci-lintの使い方
tomo1227
0
280
みんなのオブザーバビリティプラットフォームを作ってるんだがパフォーマンスがやばい #mackerelio #srenext
ne_sachirou
0
380
CSC307 Lecture 13
javiergs
PRO
0
150
CSC307 Lecture 05
javiergs
PRO
0
210
iOSアプリでクリップボードにコピーしたことをユーザーに伝えるちょうど良いフィードバックを探す
ski
0
100
GraphQL はいいぞ! ~Laravel で学ぶ GraphQL 入門~
azuki
1
160
継続的な活動で築く地方エンジニアの道
myamashii
2
360
Polarsの成長: v0.14からv1.0までの変遷と今後の展望
zerebom
1
350
SDCon2024: Enabling DevOps and Team Topologies thru architecture: architecting for fast flow
cer
PRO
0
780
はしめてのプログラミングとロボット制御
watawatavoltage
0
290
小さな開発会社を作った理由
polidog
0
1.9k
Featured
See All Featured
Atom: Resistance is Futile
akmur
261
25k
[RailsConf 2023] Rails as a piece of cake
palkan
35
4.4k
Done Done
chrislema
179
15k
Happy Clients
brianwarren
94
6.6k
Learning to Love Humans: Emotional Interface Design
aarron
269
39k
What's new in Ruby 2.0
geeforr
338
31k
Optimizing for Happiness
mojombo
373
69k
How to train your dragon (web standard)
notwaldorf
79
5.5k
Git: the NoSQL Database
bkeepers
PRO
423
64k
Being A Developer After 40
akosma
72
580k
Visualization
eitanlees
139
14k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
20
7.2k
Transcript
Andrew Godwin @andrewgodwin DJANGO and this thing called CHANNELS
Andrew Godwin Hi, I'm Django core developer Senior Software Engineer
at Likes complaining about networking
The Problem First: The Solution Then: The Future Finally:
The Problem WSGI ain't so bad
Browser HTTP Webserver Django WSGI View Handler
Browser WebSocket Webserver Django ???? ??? ????
Very hard to deadlock/cause errors Seems "Django-ish" DESIGN GOALS Scales
decently All works inside runserver
Browser WebSocket Webserver Django Channels Consumers Routing
Browser HTTP Webserver Django Channels Consumer Ch. Routing View URL
dispatch
The Solution A Series Of Channels
An ordered, first-in-first-out, at-most once queue with expiry and delivery
to only one listening consumer. Identified by a unique unicode name. WHAT IS A CHANNEL?
Producers Consumers Channel
There are standard channel names: STANDARDS Clients have unique response
channels: http.request websocket.connect websocket.receive !http.response.jaS4kSDj !websocket.send.Qwek120d
There are standard message formats: STANDARDS - HTTP request -
WebSocket close - HTTP response chunk But you can make your own channel names and formats too.
But how do we do this without making Django asynchronous?
Channels are network-transparent, and protocol termination is separate from business
logic process 1 process 2 protocol server worker server channels client socket
Async/cooperative code, but none of yours process 1 process 2
protocol server worker server channels client socket Your logic running synchronously worker server
For runserver, we run them as threads thread 1 thread
2 protocol server worker server channels client socket worker server thread 3 process 1
A view receives a request and sends a single response.
WHAT IS A CONSUMER? A consumer receives a message and sends zero or more messages.
EXAMPLE This echoes messages back: def ws_message(message): text = message.content['text']
reply = "You said: %s" % text message.reply_channel.send({ 'text': reply, })
EXAMPLE This notifies clients of new blog posts: def newpost(message):
for client in client_list: Channel(client).send({ 'text': message.content['id'], })
EXAMPLE But Channels has a better solution for that: #
Channel "websocket.connect" def connect(message): Group('liveblog').add( message.reply_channel) # Channel "new-liveblog" def newpost(message): Group('liveblog').send({ 'text': message.content['id'], })
EXAMPLE And you can send to channels from anywhere: class
LiveblogPost(models.Model): ... def save(self): ... Channel('new-liveblog').send({ 'id': str(self.id), })
EXAMPLE You can offload processing from views: def upload_image(request): ...
Channel('thumbnail').send({ 'id': str(image.id), }) return render(...)
EXAMPLE All the routing is set up like URLs: from
.consumers import ws_connect routing = { 'websocket.connect': ws_connect, 'websocket.receive': 'a.b.receive', 'thumbnail': 'images.consumers.thumb', }
EXAMPLE The HTTP channel just goes to the view system
by default. routing = { # This is actually the default 'http.request': 'channels.asgi.ViewConsumer', }
The Future What does it all mean?
WSGI
WSGI 2?
ASGI channels.readthedocs.org/en/latest/asgi.html
channel_layer.send(channel, message) channel_layer.receive_many(channels) + message standards + extensions (groups, stats)
Daphne HTTP/WebSocket ASGI server asgiref Memory layer, conformance suite, WSGI
adapters asgi_redis Redis-based channel layer
Raw ASGI app example: while True: channel, message = layer.receive_many(
["http.request"], block = True, ) if channel is None: continue layer.send( message['reply_channel'], { 'content': 'Hello World!', 'status': 200, } )
Django 1.10
Django 1.10 And 1.8, 1.9 as a third-party app
It's all optional. No need to change anything if you
don't want to use channels.
pip install channels channels.readthedocs.org
Thanks. Andrew Godwin @andrewgodwin