I wrote a Finite-State Machine library, with Ecto support (playing nicely with Schemas, Changesets, and Ecto.Multi)
I built it to solve a few problems I had in a current project, and some of the existing similar packages were lacking some things I needed, such as:
- integrating state transitions, and their callbakcs into a larger DB transaction
- support different ecto changesets upon leaving/entering specific states
Check it out at https://github.com/subvisual/fsmx
In your own words, how would you compare this with the built-in gen_statem which is very process- and behavior-centric and not so much about data structures or pure functions? (It’s “just” a sophisticated/opinionated GenServer, more or less.)
Hi. Good question
I think both represent the same concept, but serve different purposes.
gen_statem is process-oriented, as you said. In my case (both in a current project, and a couple of past projects where I felt the need for a similar pattern) I actually wanted to model persistent state, and not necessarily a process.
The example I’m dealing with right now was an Ecto model that already existed before this fsm concept was introduced to it. It now contains a state field, some behaviour that is necessary when entering/leaving certain states, and some specific validations on the changeset, also depending on the state
Modeling this with gen_statem would require a process to deal with each individual instance of the schema, which already changes a whole lot the approach we use in the rest of the existing code. In this case I’m just dealing with database updates, and a couple of side effects of some particular cases (such as sending an email, which
Bamboo already defers to an async task