Just dropping by to share PhonixLiveState, a lib I’ve just published.
It’s still VERY RAW, but already in a reasonably usable state.
The idea is to define a state in a process separate from the liveview, which enables some interesting features:
Easier to isolate information in a state
Auto recovery in case the liveview crashes
Share states between liveviews within the cluster
Share state between a Phoenix Controller and a LiveView
Once connected, you can access your shared state in the template with @live_assigns
Yes, the assign is automatically updated when any client makes a change
On top of that, I added a few extra features:
Auto shutdown with TTL (configurable) when no clients are connected: prevents zombie processes
Read/write permissions with ACL for group/public
Keep in mind that it was originally built to fulfill my own needs on another project, so it might not fit perfectly into your workflow (but I tried my best to keep it use-case agnostic).
I’m interested in that I am solving a similar problem at the moment: spawning a GenServer to handle a meeting (as in a digital version of an IRL meeting) so I get the use case.
However, it’s not clear what problems this library solves beyond what you get from OTP GenServer/Supervisor & co.
Good idea, well documented and written code. While I was reading the code, I discovered these questions/issues:
use PhoenixLiveState, :client is essentially a noop. It raises no error, but it also exports no hooks or anything. Why?
If I understood the code correctly, this solution appears to be none from CAP. It’s not consistent or partition tolerant because state server is started under the global name, and when split happens and some new live view mounts in the partition without state server, it will spawn a second server with the same name, which will result in two servers having different state. When split is resolved, one server will be just killed, since server does not implement any callbacks for state handover. It is also not available, because when cluster splits, the views which are in different partition then the state server, will just crash during the GenServer.call to the state server.
When two views do the same action (consider the messages list from the README example), their order will be indefinite and it’s even worse, cause the action which will hit the state server first will be just overwritten by the second one.
Why add ACL to this solution?
It seems that state server spawning is unbalanced, in a sense that the state server always spawns on the node where the first live view with this key mounts
But I like the idea and most of the interface, so I have these suggestions about how to improve the solution:
Decide on CAP. There are AP and CP solutions which I can suggest. First is AP, investigate Delta CRDT algorithms, Merkle Map versions, You can use library Horde (or is it Swarm) which utilizes this algorithm as a reference. If you want to have CP solution, I would suggest to not use the global and implement some persistent hashring to decide on the node where the state server spawns (no matter where the liveview was first mounted).
I don’t see the use case for ACL, but even if there is one, it’s not that hard to implement it on top of the key-valye sync. Doing it inside the library just blurs the scope and, personally for me, looks odd.
Make most logs debug or at least add some metadata so that users of the library could filter these messages out
I believe that every distributed algorithm must have a good doc with implementation details and choice it makes in order for users to understand the possible drawbacks and failure scenarios.
I don’t know any forum related to distributed systems and distributed system’s algorithms in general, because “distributed system” is kinda true for almost every new program nowadays
But I think that elixirforum or erlangforums is a good place to create discussions about these problems, since “solving X in Elixir” is always an acceptable topic here and Elixir is the best language to solve problems of distributed systems. If you have some distributed systems problem at your work, I am also ready to provide some expertise for a reward.