Stateright: A model checker for implementing distributed systems
github.com
github.com
It includes a comparison w/ TLA+/TLC for those familiar with those technologies.
>Cloud service providers like AWS and Azure leverage verification software such as the TLA+ model checker to achieve the same goal, but whereas those solutions typically verify a high level system design, Stateright is able to verify the underlying system implementation in addition to the design (along with providing other unique benefits explained in the "Comparison with TLA+" chapter). On the other end of the spectrum are tools such as Jepsen which can validate a final implementation by testing a random subset of the system's behavior, whereas Stateright can systematically enumerate all possible behaviors within a specified model of the system.
One recommendation for the guide: you know the tool much better than the audience, so you're going to underestimate how hard it is for readers to follow. It's something all experts do all the time. Have you considered smaller, sorter step examples?
Thank you for the suggestion as well. Do you have thoughts on specific places where I should either split a chapter and/or associated project to make the ramp up more incremental?
1. Actor systems; writing code with Stateright
2. Model checking; model checking with Stateright
3. The actual problems we want to apply Stateright too
Right now you're teaching all three of those simultaneously; I think it would be better if you could scaffold, or introduce the ideas one at a time. For example, showcasing setup and modelchecking first on a property simpler than linearizability. I've been really fond of race-free critical sections for concurrent properties recently, just because it has relatively fewer moving parts.
Sorry these thoughts are a little disjointed, writing guides is really really hard
EDIT: probably not something that would be directly helpful to people, but one thing I'd personally be very interested in reading is how this all works under the hood. If I understanding correctly, you're making each Actor inspectable by `ActorModel`, which then acts as an orchestrator and records history. Is that correct?
1. A high level overview of distributed systems and the actor model. Perhaps no code. 2. A Rust intro via an implementation of the Actor trait (which is where the `on_msg`/etc methods can be explained). The chapter would include the same Actor implementation but would omit verification. 3. An intro to system properties, nondeterminism, and verification via model checking. Here the book could postpone a discussion of linearizability and instead indicate a simpler property for the actor system. Linearizability could then be introduced when discussing replication later in the book.
Most stuff can be done without any of the fancy containerization and such solutions.
How would you prove to the client that your solution implements these requirements? Modeling the system using a language like TLA+ is one way of doing that.
There is no reason to start implementing things, if your design is wrong.
Formal Specification proves your design, while Formal Verification proves your implementation.
As far as I understand this project - Stateright does both (i.e. 2-in-1). Kind of executable model?
It’s important to clarify that this doesn’t provide a proof of correctness, but it can dramatically improve confidence in both the design and implementation compared with fuzz testing, for example. This is done by exhaustively enumerating possible nondeterministic outcomes (e.g. due to message reordering) within specified constraints (e.g. up to S servers and C clients performing X operations…).
Examples:
SD Paxos: https://github.com/stateright/stateright/blob/master/example...
ABD (linearizable register algorithm): https://github.com/stateright/stateright/blob/master/example...
If you don't have that (say you're using TLA+), one really promising technique is to generate behavioral traces and then refine those into code tests. I know a few companies have done this successfully, and I've been working on some examples of how it's done, but to my knowledge there's no battle-tested tooling that do this automatically. It's all bespoke for now.
Having a specification which is guaranteed to be correct before implementation begins is a programmer’s wet dream.
One of my dreams is to flatten that learning curve. I don't think we'll ever make these tools effortless, but I think it's possible to reach a point where "these tools are too hard to learn" isn't a barrier anymore.
(Even then, I imagine a lot of people will learn some formal specification, and think "this isn't useful for me", and never touch them again. And that's fine. But I want anybody to be able to reach the point where they can make that decision, as opposed to feeling like they're locked out by default. We have a long way to go, but I think we're considerably further along than we were five years ago.)
> Having a specification which is guaranteed to be correct before implementation begins is a programmer’s wet dream.
I wouldn't say guaranteed to be correct, but at least it's, like, closer to correct? Less likely to have horrific bugs, or bizarre edge cases in the requirements that nobody notices until neck deep into the implementation. Stuff that increases founded confidence.
That said, implementing a consensus algorithm is quite hard. Modeling and testing is much harder, there is even a language just for this purpose; TLA+ [0].
Whatever things you end up deciding, does your system, where many people are reserving, cancelling, and re-reserving over long periods of time, guarantee all of the client's expectations?