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
gen_statem - OTP's Unsung Hero
Search
Andrea Leopardi
April 04, 2025
Programming
2
310
gen_statem - OTP's Unsung Hero
Given at AlchemyConf 2025 in Braga, Portugal.
Andrea Leopardi
April 04, 2025
Tweet
Share
More Decks by Andrea Leopardi
See All by Andrea Leopardi
The Umbrella and the Range
whatyouhide
0
38
The World is a Network (and We Are Just Nodes)
whatyouhide
1
240
BEAM: The Perfect Fit for Networks
whatyouhide
1
240
Update from the Elixir team - 2022
whatyouhide
0
450
Testing Asynchronous OTP
whatyouhide
1
560
Elixir Sightseeing Tour
whatyouhide
0
460
Mint - Disrupting HTTP clients
whatyouhide
0
290
BEAM Architecture Handbook
whatyouhide
7
2.9k
The Evolution of a Language
whatyouhide
0
190
Other Decks in Programming
See All in Programming
How to stabilize UI tests using XCTest
akkeylab
0
110
CSC307 Lecture 14
javiergs
PRO
0
470
野球解説AI Agentを開発してみた - 2026/02/27 LayerX社内LT会資料
shinyorke
PRO
0
200
CSC307 Lecture 15
javiergs
PRO
0
240
ふつうの Rubyist、ちいさなデバイス、大きな一年
bash0c7
0
840
Swift ConcurrencyでよりSwiftyに
yuukiw00w
0
260
grapheme_strrev関数が採択されました(あと雑感)
youkidearitai
PRO
1
210
AHC061解説
shun_pi
0
360
AI時代でも変わらない技術コミュニティの力~10年続く“ゆるい”つながりが生み出す価値
n_takehata
2
720
Agent Skills Workshop - AIへの頼み方を仕組み化する
gotalab555
15
8.5k
RubyとGoでゼロから作る証券システム: 高信頼性が求められるシステムのコードの外側にある設計と運用のリアル
free_world21
0
270
モジュラモノリスにおける境界をGoのinternalパッケージで守る
magavel
0
3.5k
Featured
See All Featured
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Everyday Curiosity
cassininazir
0
160
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Tell your own story through comics
letsgokoyo
1
840
The Cost Of JavaScript in 2023
addyosmani
55
9.8k
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
140
エンジニアに許された特別な時間の終わり
watany
106
240k
How to Think Like a Performance Engineer
csswizardry
28
2.5k
Marketing to machines
jonoalderson
1
5k
Designing Powerful Visuals for Engaging Learning
tmiket
0
270
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.9k
Transcript
None
Andrea Leopardi @whatyouhide
None
None
None
gen_statem
but why?!
FSM
FSM initial state states state transitions
None
chilling_and_looking_sad_for_no_reason
None
None
Finite?
Age of AI
gen_statem
None
@behaviour :gen_statem
None
init/1 terminate/3 code_change/4 format_status/2
def callback_mode do :state_functions end
handle_call/3 handle_cast/2 handle_info/2
<state_name>/3
<state_name>( event_type, event_content, data )
<state_name>( event_type, event_content, data )
<state_name>( event_type, event_content, data )
def handle_cast( {:put_coin, coin}, state ) do {:noreply, update_in(state.credit, &add_coin/1)}
end
def accepting_coins( :cast, {:put_coin, coin}, data ) do {:keep_state, update_in(data.credit,
&add_coin/1)} end
None
None
def accepting_coins( {:call, from}, {:press_button, beverage}, data ) do if
enough_credit?(data, beverage) do dispense_beverage(data, beverage) actions = [{:reply, from, :ok}] {:next_state, :dispensing, data, actions} else # ... end end
actions = [{:reply, from, :ok}] {:next_state, :dispensing, data, actions}
that’s kind of it?
Feature tour
Postponing events State enter callbacks Timeouts (state, event, named) Internal
events Non-finite state machines
Postponing events
None
def dispensing(:cast, {:add_coin, _}, data) do actions = [:postpone] {:keep_state_and_data,
actions} end def accepting_coins(:cast, {:add_coin, _}, data) do # Normal implementation end
“State enter”
def callback_mode do [ :state_functions, :state_enter ] end
def accepting_coins(:enter, _old_state, data) do update_display(data.credit) :keep_state_and_data end
Timeouts
Event timeouts
def accepting_coins(:cast, {:put_coin, coin}, data) do {:keep_state, update_in(data.credit, &add_coin/1)} end
def accepting_coins(:cast, {:put_coin, coin}, data) do actions = [ {:timeout,
to_timeout(second: 30), :give_back_coins} ] {:keep_state, update_in(data.credit, &add_coin/1), actions} end def accepting_coins(:timeout, :give_back_coins, data)
{:timeout, to_timeout(second: 30), :give_back_coins} def accepting_coins(:timeout, :give_back_coins, data)
State timeouts
def dispensing(:enter, _old_state, _data) do actions = [ {:state_timeout, to_timeout(minute:
1), :stuck} ] {:keep_state_and_data, actions} end def dispensing(:state_timeout, :stuck, data) do # Call for help, the machine got stuck. end
Named timeouts
def init(options) do actions = [ {{:timeout, :self_health_check}, to_timeout(hour: 1),
:no_content} ] {:ok, :idle, data, actions} end def idle({:timeout, :self_health_check}, _content, data) do # ... end
def accepting_coins({:timeout, :self_health_check}, _, _) do {:keep_state_and_data, [:postpone]} end def
dispensing({:timeout, :self_health_check}, _, _) do {:keep_state_and_data, [:postpone]} end
{:timeout, ms, content} {:state_timeout, ms, content} {{:timeout, :some_name}, ms, content}
“Internal” events
def disconnected({:timeout, :reconnect}, _, _data) do {:keep_state_and_data, {:next_event, :internal, :connect}}
end
Non-finite state machines
def callback_mode do :handle_event_function end
def accepting_coins( :cast, {:put_coin, coin}, data ) do # ...
end
def handle_event( :cast, {:put_coin, coin}, :accepting_coins, data ) do #
... end
def handle_event( event_type, event_content, current_state, data )
def handle_event( :cast, {:put_coin, coin}, {:accepting_coins, credit}, data ) do
new_state = {:accepting_coins, credit + coin} {:next_state, new_state, data} end
Use cases
None
GenServer :gen_statem or
def handle_call(call, from, %{user: nil}) def handle_call(call, from, %{user: %User{}})
def handle_call(call, from, %{user: %Admin{}})
def no_user({:call, from}, _, _) def user({:call, from}, _, _)
def admin({:call, from}, _, _)
Connections!
DBConnection Redix HTTP/2 (?)
None
state/named timeouts -> reconnection w/ backoff event timeouts -> keepalive
postponed events -> retrying requests
Workflow engines IoT sensors …
Wrapping up
Timeouts
No Elixir wrapper it’s fine
Data structures Processes vs
HTTP/2 stream state machine diagram
Composability
None
Resources Wikipedia Docs
Thanks! @whatyouhide AlchemyConf 2025