How I taught Rust’s type system to refuse my own parallel-Redux data races, with one false start and one mind-shift.
There’s a class of bug I’ve spent more nights chasing than I care to remember. The kind that only happens under load, vanishes when you attach a debugger, and takes three engineers a weekend to corner. Data races.
Rust’s borrow checker prevents most of them at the value level. But not all of them, and definitely not the question that interested me here: can the compiler refuse to build a parallel reducer pipeline where two reducers might write to the same piece of state?
Turns out yes. This post is the story of how I got there in ruxe, my Redux-flavored Rust learning library.
What is Redux?#
Redux is a state management pattern. It got famous in frontend JavaScript but the shape is more general; any system where state changes through discrete events fits the model.
flowchart LR User([User code]) -->|dispatch event| Store Store -->|state + event| Reducer Reducer -->|new state| Store Store -->|read| User
Three rules make Redux what it is.
One: a single source of truth. The state is owned by the store, nothing else.
Two: the state is immutable from outside. You don’t poke it directly. You dispatch events (the JS world calls them “actions”) that describe what happened.
... continue reading