ryanrborn
A long-running GenServer holds orders, positions, strategy state, and operational flags for a system trading real capital. The post walks the actual state struct, the three categories of data inside it, the persistence model (write to the database before the broker, push heavy work to Oban, never persist candles), and the design principles that fell out of running it in production — including why mid-roll restarts refuse to resume rather than guess.
Trending in Blog Posts
Hey folks,
I just published a post about Hologram’s funding and where the project goes next - the short version:
Curiosum as Main Spons...
New
I am seeing a lot of aplications of Argumentum ad Vericundiam in software discussions. They do link some piece of writing and point us to...
New
Hi all,
In this article, I make the case for each test owning its setup.
Usually I forbid my AI agents to use the setup callbacks; I mu...
New
As I’ve leaned into AI code generation on LocalCents, the volume I ship has climbed, and my worry shifted from any single change to the l...
New
A while back, I had to process millions of database updates in a legacy system that was already hitting its 64 GB RAM limit, so scaling t...
New
I recently figured out how to the the Rust hotpath profiling crate running in an elixir benchmark script (for profiling NIFs). I had some...
New
This article demonstrates how to build a minimal stateful process using only Elixir’s core concurrency primitives: spawn/1, send/2, recei...
New
Other Trending Topics
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #blog-post
- #phoenix_html
- #iex
- #graphql
- #ai
- #genstage
- #elixirconf-us
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex










Showing Posts 1 to 10- Show Best Posts
- Show All Posts (oldest first)
- Show All Posts (newest first)
derek-zhou
I suggest to flatten them into the parent struct, use tuples, or use new structs. A map is a bad choice because with a map I have to write the keys and I will make typos.
Boolean flags are bad choices to encode state machine states (sooner you will find some combinations are illegal). Ideally, they should use enum types but since Elixir does not have a true enum type I’d just use atoms.
ryanrborn
Thanks Derek — both fair, and both in the direction I’d take this code if I were refactoring it now.
On the maps: bare maps with conventional keys are a typo waiting to happen, you’re right. They ended up that way because each handle carries module-specific context whose shape varies by implementation — a strategy handle for order-flow logic holds different keys than one for a calendar roll. A struct with module: and a free-form context: map would give me a static field on the part that actually dispatches without forcing a schema on the part that legitimately varies. That’s the refactor I’d make.
On the booleans: the case is strongest for portfolio_heat_warned / portfolio_heat_blocked, which are an escalation ladder rather than two independent flags. Collapsing them into portfolio_heat: :ok | :warned | :blocked makes the “blocked but not warned” state unrepresentable, which is exactly what you’d want. trading? and rolling? are closer to genuinely independent — rolling can be in progress while trading is administratively halted — but I’d still take a tagged status to force the question of which combinations are actually reachable.
Appreciate the careful read.
mudasobwa
Either we call if FSM, or we have flags, tertium non datur. State machine is not an object having
statefield. There should be a single source of truth and any flags spread the responsibility inevitably resulting in a diverged inconsistent state sooner or later.FSM has transitions and the transition callback in the only place where the decision might have happened.
ryanrborn
Reading you again, your target is derek-zhou’s atoms-as-cure, but the same point lands on the concession I made to them. Renaming
rolling?tostatus: :rollingdoesn’t make it a state machine; it just retypes the flag. The FSM lives in the transition function, not the field type. That’s the right correction.The struct as written has multiple operational flags doing what should be the work of one transition callback. A single transition function owning every legal move (and making the illegal ones structurally impossible) is the shape that wants to exist.
:gen_statemis the obvious BEAM tool; a hand-rolledstep/3plus pattern-matched events is the lighter version.What I’m curious about is where you’d draw the line for what belongs inside the transition function versus what’s an input to it. Some of those flags feel like events the FSM consumes, not states it carries, but I’d rather see you lay it out than guess. The distinction is one a lot of posts get wrong, this one included.
mudasobwa
I would not draw this line whatsoever. As an author of Finitomata, I spent a lot of time playing with different ideas and I came up with the simplest one: each transition callback has an internal state and an incoming payload with each event.
Vidar
I find using flags for state machines confusing. I have vague memories of designing state machines using binaries, truth tables and Karnaugh maps. Binaries would be similar to flags, so it can of course be done, but I rather not.
In my possibly naive mind deterministic finite state machines have only a single state at any time, only one valid transition at any time, and have transition callbacks to do side effects.
mudasobwa
Correct.
Incorrect.
Not necessarily.
Vidar
How do you do deterministic if there are several valid transitions from a state? It is certainly easier if there is only one.
mudasobwa
Only one state is even easier, but not as handy. Deterministic finite automaton - Wikipedia
Vidar
If I read that correctly that depends on using a Mealy state machine with inputs as added guides for a deterministic output, rather than a Moore state machine where there is only present state. For a deterministic Moore state machine I can not understand how there can be more than one valid output at a time?
I’ve used Finitomata earlier so thanks for that!