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
Scalable dist-sys from grounds up
Search
udit
April 28, 2019
Technology
220
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Scalable dist-sys from grounds up
udit
April 28, 2019
More Decks by udit
See All by udit
Road to masterless multi-node distributed system in Elixir
yudistrange
0
59
Other Decks in Technology
See All in Technology
自律型 AI をセキュアに実装!Gemini と MIG で作る動的コード実行環境
recruitengineers
PRO
1
230
並行性の問題を防げ!実践トランザクション入門
occhi
0
280
Deep Data Security 機能解説
oracle4engineer
PRO
2
720
Claude Code本は、どのように執筆チームで書かれたか
oikon48
0
320
IoTデバイスを繋げるプロトコルMatterをAndroidで使用する方法
harutiro
0
120
形式手法を使って仕様をコーディングしよう
mikanichinose
0
190
継続的なAIコスト最適化
bgpat
1
220
[AWS 秋のクラウドオペレーション祭り 2026]AWS DevOps Agentで変わるリリースと運用対応 ~リリース管理機能と Directed actions のご紹介~
furuton
4
1.1k
分析AIエージェントを育てる、動く環境を育てる
codatum
0
320
実体験から学ぶ分析エージェントの開発と運⽤
recruitengineers
PRO
4
1.4k
LLM機能を自作して分かるSnowflake Cortex AIの強み
nayuts
0
320
おそらく日本で唯一のDevRelインターン生として
husengs7
0
170
Featured
See All Featured
エンジニアに許された特別な時間の終わり
watany
109
250k
The Cost Of JavaScript in 2023
addyosmani
55
10k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
Optimising Largest Contentful Paint
csswizardry
37
4k
Are puppies a ranking factor?
jonoalderson
2
4k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
300
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
550
The Curious Case for Waylosing
cassininazir
1
560
Odyssey Design
rkendrick25
PRO
2
860
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
570
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.5k
Transcript
scalable dist-sys from the grounds up in Elixir
whoami udit @ nilenso
agenda why elixir/erlang under the hood build you a live
game for great good build you a better live game for greater good
why elixir / erlang
why dist-sys are hard? state computation reliability order . .
.
why elixir/erlang asynchronous message passing no sharing fault tolerance
why elixir/erlang distributed out of the box primitives for concurrency
under the hood
beam Bjorn’s erlang abstract machine bytecode ~ erlang / Elixir
/ Gleam / LFE etc
process light weight - green thread communicate via message passing
single threaded
process process control board heap stack
process garbage collection when: heap meets stack runs on process
schedule compaction vs full copy
process schedulers process queues soft pre-emptive
process defmodule RcDemo.Echo do def start() do receive do :exit
-> IO.puts("Shutting down") x -> IO.inspect(x, label: "Received Message on #{inspect(self())}: ") start() end end end
process registration noname :local :global pg2 swarm Registry (elixir)
supervisor reliability monitor other process
gen_server generic server better abstraction over state still a process
defmodule RcDemo.EchoGenServer do use GenServer def start(), do: GenServer.start(__MODULE__, nil) def init(nil), do: {:ok, %{}} def handle_cast(message, state) do IO.inspect(message, label: "Cast:") {:noreply, state} end def handle_call(message, from, state) do IO.inspect(message, label: "Call:") :timer.sleep(2000) {:reply, :called, state} end end
gen_server call GenServer.call(pid, :hi, 1000) cast GenServer.cast(pid, :hello) info send(pid,
:info)
distributed nodes fully connected mesh network heartbeat
None
a live game for great good
listener def receive_message(socket, receive_callback) do case :gen_tcp.recv(socket, 0) do {:ok,
message} -> :gen_tcp.send(socket, "Message received\n") {m, f, a} = receive_callback apply(m, f, a ++ [message]) receive_message(socket, receive_callback) _otherwise -> IO.inspect("Shutting down the socket") end end def listen(port, accept_callback) do {:ok, socket} = :gen_tcp.listen(port, [:binary, reuseaddr: true]) accept_connection(socket, accept_callback) end def accept_connection(listen_socket, accept_callback) do {:ok, accept_socket} = :gen_tcp.accept(listen_socket) spawn(fn -> {m, f, a} = accept_callback receive_callback = apply(m, f, a ++ [accept_socket]) receive_message(accept_socket, receive_callback) end) accept_connection(listen_socket, accept_callback) end
one for all defmodule RcDemo.Game.OneToAll.SingleActor do def start (port), do:
GenServer.start_link( __MODULE__, port, name: {:global, Single}) def init(port) do spawn(fn -> TcpListner.listen(port, {__MODULE__, :noop, []}) end) {:ok, %{}} end def noop(_), do: {__MODULE__, :incoming, []} def incoming(message), do: GenServer.cast(Single, {:incoming, message}) def handle_cast({:incoming, message}, state) do IO.inspect(message, label: "Received in GenServer with pid #{inspect self()}") {:noreply, state} end
one for all
one for all 1 : n single thread of execution
for all incoming message message queue build up no fault tolerance
one for one defmodule RcDemo.Game.OneToOne.Master do def start(port), do: GenServer.start_link(__MODULE__,
port, name: Master) def init(port) do spawn(fn -> TcpListner.listen(port, {__MODULE__, :new_connection, []}) end) {:ok, %{}} end def new_connection(socket) do {:ok, pid} = Worker.start(socket) {Worker, :incoming, [pid]} end end defmodule RcDemo.Game.OneToOne.Worker do def start(_socket), do: GenServer.start_link(__MODULE__, []) def init(_), do: {:ok, %{}} def incoming(pid, message), do: GenServer.cast(pid, {:incoming, message}) def handle_cast({:incoming, message}, state) do IO.inspect(message, label: "Received in Worker with pid: #{inspect self()}") {:noreply, state} end end
one for one 1 : 1 can process responses from
players faster large process queue on schedulers
n to m defmodule RcDemo.Game.Balanced.Master do def init(port) do worker_pids
= Enum.reduce(1..2, [], fn _x, acc -> {:ok, pid} = Worker.start() [pid] ++ acc end) spawn(fn -> TcpListner.listen(port,{__MODULE__, :new_connection, [[worker_pids]]}) end) {:ok, %{}} end def new_connection([worker_pids], socket) do worker_index = hash_socket(socket) worker_pid = Enum.at(worker_pids, worker_index) {Worker, :incoming, [worker_pid]} end defp hash_socket(_socket), do: :rand.uniform(2) – 1 end defmodule RcDemo.Game.Balanced.Worker do def init(_params), do: {:ok, %{}} def incoming(pid, message), do: GenServer.cast(pid, {:incoming, message}) def handle_cast({:incoming, message}, state) do IO.inspect(message, label: "Received in Worker with pid: #{inspect self()}") {:noreply, state} end end
n to m n : m shard player
None
a live game for greater good
addendum supervision
addendum differentiate processes
addendum distributed processes
addendum islands
fin
references Erlang Garbage Collection Details and Why It Matters The
beam book Discord Blog Whatsapp’s island architecture Elixir School Elixir Official Documentation Demo code repo Slides
thank you @yudistrange