jpbecotte

jpbecotte

How to handle states sync in an «offline first» approach?

Hello all,

The context is simple: When a user joins the main lobby channel of my app, it receives its state. Then, the user interacts over the front-end UI, where its state is mutated.

So I see two paths here:

Path #1: When a mutation occurs, send a request thru the socket (or over API), then wait for the server to process the mutation.

This is the old request-response mechanism and it may suit a lot of needs. But it has caveats: the front-end must be constantly connected over an internet connection. Plus, there might be a delay between the mutation occurs and its acknowledgment from the server.

Path #2: When a mutation occurs, simply mutate local state. Syncing is made in background with a presence mechanism. If a client goes offline for any reason, then its state gets synced next time it reconnects.

My question is: what is the best way to implement path 2?

I’ve looked at Phoenix.Tracker, which «use a heartbeat protocol and CRDT to replicate presence information across a cluster in an eventually consistent, conflict-free manner» and it looked promising. Trackers work with presence metadata. But I read in the Phoenix.Presence doc: « Presence metadata should be minimized and used to store small, ephemeral state, such as a user’s “online” or “away” status.».

So I am confused. Is Phoenix.Tracker the best way to implement this or there is a better way of doing it?

Thanks in advances!

JP

Most Liked

LostKobrakai

LostKobrakai

Offline first is just a more fancy way to say distributed state. So all the solutions / tradeoffs and issues of the latter apply here. Phoenix Tracker for example uses CRDTs to distribute the presence of something/someone in a channel. The metadata is just a bag of data assigned to that presence, which is not merged in any way as far as I know. It’s simply replaced.

So you’d need to check if you problem can be solved using the particular solution, but there are many other ways for merging potentially conflicting state all with their own set of tradeoffs.

Where Next?

Popular in Questions Top

Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
Werner
Hi, I’m using Ubuntu 18.04 and after updating to OTP-24.0 yesterday i have this warning when I run “mix local.hex”: 14:57:30.512 [warn] ...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
gonzofish
I’m currently trying to understand how to join three tables using Ecto. All the examples I’ve seen use 2, so maybe I’m just missing somet...
New
Mooodi
Given a string, how can I get access to its character by index? Enum.at("my_string", 2) doesn't work. Or rather, not char, but a substr...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

Other popular topics Top

lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
273 38985 115
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

We're in Beta

About us Mission Statement