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
Concurrent and Resilient Connections to Outside...
Search
Andrea Leopardi
May 11, 2016
Programming
1
320
Concurrent and Resilient Connections to Outside the BEAM
Andrea Leopardi
May 11, 2016
Tweet
Share
More Decks by Andrea Leopardi
See All by Andrea Leopardi
gen_statem - OTP's Unsung Hero
whatyouhide
2
260
The World is a Network (and We Are Just Nodes)
whatyouhide
1
220
BEAM: The Perfect Fit for Networks
whatyouhide
1
200
Update from the Elixir team - 2022
whatyouhide
0
410
Testing Asynchronous OTP
whatyouhide
1
530
Elixir Sightseeing Tour
whatyouhide
0
440
Mint - Disrupting HTTP clients
whatyouhide
0
260
BEAM Architecture Handbook
whatyouhide
7
2.8k
The Evolution of a Language
whatyouhide
0
160
Other Decks in Programming
See All in Programming
オープンセミナー2025@広島LT技術ブログを続けるには
satoshi256kbyte
0
160
ECS初心者の仲間 – TUIツール「e1s」の紹介
keidarcy
0
150
さようなら Date。 ようこそTemporal! 3年間先行利用して得られた知見の共有
8beeeaaat
2
1.3k
意外と簡単!?フロントエンドでパスキー認証を実現する WebAuthn
teamlab
PRO
2
620
「手軽で便利」に潜む罠。 Popover API を WCAG 2.2の視点で安全に使うには
taitotnk
0
750
OSS開発者という働き方
andpad
5
1.7k
Protocol Buffersの型を超えて拡張性を得る / Beyond Protocol Buffers Types Achieving Extensibility
linyows
0
110
Vue・React マルチプロダクト開発を支える Vite
andpad
0
110
Updates on MLS on Ruby (and maybe more)
sylph01
1
180
Kiroの仕様駆動開発から見えてきたAIコーディングとの正しい付き合い方
clshinji
1
200
コンテキストエンジニアリング Cursor編
kinopeee
1
760
パッケージ設計の黒魔術/Kyoto.go#63
lufia
3
430
Featured
See All Featured
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.4k
VelocityConf: Rendering Performance Case Studies
addyosmani
332
24k
Testing 201, or: Great Expectations
jmmastey
45
7.6k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.9k
Stop Working from a Prison Cell
hatefulcrawdad
271
21k
Optimising Largest Contentful Paint
csswizardry
37
3.4k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
126
53k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
33
2.4k
The Cult of Friendly URLs
andyhume
79
6.6k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
252
21k
Thoughts on Productivity
jonyablonski
70
4.8k
Transcript
outside CONCURRENT RESILIENT and CONNECTIONS to the BEAM
ERLANG VM mnesia message passing ets
ERLANG VM key-value store relational db message queue
ERLANG VM key-value store relational db message queue
the outside world is SCARY
ANDREA LEOPARDI @WHATYOUHIDE
Gothenburg, Sweden
FOOTBALL ADDICTS
GENSERVER TCP
SILLY the way
defmodule Redis do def command(cmd) do end end
defmodule Redis do def command(cmd) do {:ok, sock} = :gen_tcp.connect(...)
:gen_tcp.send(sock, encode(cmd)) {:ok, data} = :gen_tcp.recv(sock, 0) :gen_tcp.close(sock) decode(data) end end
defmodule Redis do def command(cmd) do {:ok, sock} = :gen_tcp.connect(...)
:gen_tcp.send(sock, encode(cmd)) {:ok, data} = :gen_tcp.recv(sock, 0) :gen_tcp.close(sock) decode(data) end end
defmodule Redis do def command(cmd) do {:ok, sock} = :gen_tcp.connect(...)
:gen_tcp.send(sock, encode(cmd)) {:ok, data} = :gen_tcp.recv(sock, 0) :gen_tcp.close(sock) decode(data) end end
defmodule Redis do def command(cmd) do {:ok, sock} = :gen_tcp.connect(...)
:gen_tcp.send(sock, encode(cmd)) {:ok, data} = :gen_tcp.recv(sock, 0) :gen_tcp.close(sock) decode(data) end end
defmodule Redis do def command(cmd) do {:ok, sock} = :gen_tcp.connect(...)
:gen_tcp.send(sock, encode(cmd)) {:ok, data} = :gen_tcp.recv(sock, 0) :gen_tcp.close(sock) decode(data) end end
defmodule Redis do def command(cmd) do {:ok, sock} = :gen_tcp.connect(...)
:gen_tcp.send(sock, encode(cmd)) {:ok, data} = :gen_tcp.recv(sock, 0) :gen_tcp.close(sock) decode(data) end end
opening NEW connections is EXPENSIVE
GENSERVER keeping the socket in a
TWO WAYS blocking non-blocking
TWO WAYS blocking
CLIENT GENSERVER socket socket send() recv()
defmodule Redis do def command(conn, cmd) do sock = checkout(conn)
# send and recv checkin(conn, sock) end end
defmodule Redis do def command(conn, cmd) do sock = checkout(conn)
# send and recv checkin(conn, sock) end end
{:error, :checked_out} :queue.in() VS
POOLING :|
TWO WAYS non-blocking
active: true {:noreply, _} + GenServer.reply/2 +
client Redis client client GenServer
tcp is FULL DUPLEX
client Redis client client Sender Receiver
TWO WAYS blocking non-blocking copies less data + needs pooling
- doesn't use full duplex - enc/dec on client + - copies more data + doesn't need pooling + uses full duplex - enc/dec in server
RESIL IENCY
Redis GenServer
Redis GenServer
{:tcp_closed, reason} backoff + reconnect
hex.pm/packages/connection gen_
Connection GenServer
init/1 connect/2 disconnect/2 handle_call/3 handle_cast/2 handle_info/2 terminate/2 code_change/3 {:disconnect, reason,
state} {:backoff, timeout, state}
sync/async CONNECT
SYNC start_link {:ok, pid} init() connect
ASYNC start_link {:ok, pid} init() connect connect()
You now allow initializations with fewer guarantees: they went from
"the connection is available" to "the connection manager is available". Fred Hebert
CONNECTION TALKING CONCURRENCY RESILIENCY
@whatyouhide