Elixir-desktop as part of a cluster?

Hey Folks,

I was very excited to learn about elixir-desktop. Thanks for your work :slight_smile:

So I was wondering if elixir-desktop could be used to more easily implement a webapp that also runs on desktop and has some offline functionality.

Normally you would have a stack like this:

  • Server Backend (e.g. Phoenix)
  • Web Frontend (e.g. Phoenix)
  • Electron App (e.g. React)

To connect the Electron app you would be required to implement an API and the syncing process would be rather obnoxious.

My question is regarding clustering. Maybe I have some mistaken thinking regarding the concepts.

The way I see it you could have one code base with certain parts conditionally starting based on wether the code is running on a sever or a desktop client.

Now the question:
Could you join the desktop app to your distributed elixir cluster as soon as it is online? Would you need some sort of wireguard setup (this is where I lack experience) between the clients and the server to ensure the connection?
As soon as your client is joined you could act on live data and sync any changes the client has been made offline.

If that could be possible I see a lot of potential in a setup like that :slight_smile:

Thanks,
Nick

In theory this is surely possible. It’s TCP connections between nodes.

In practise clustering is not build for that usecase. Most importantly there’s no security boundries between clustered nodes. But also Node naming can become tricky with various networks involved. By default beam clustering uses a full mesh, so all the desktop apps would want to connect to each other as well (just just to servers).

1 Like

While it could be heavy handed, there are ways to create custom network topologies that are not fully meshed. For example: GitHub - lasp-lang/partisan: High-performance, high-scalability distributed computing for the BEAM.

As soon as a node connects to a topology, I believe it has full access to run anything on any connected node. If you’re making a desktop/server sync protocol, the desktop side would likely have to be viewed as “untrusted”, so I’m not sure if this would be safe unless it is a single-tenant application.

1 Like

i woudn’t recommend clustering outside of your private network.
if you’re doing so, make sure to use tls.

i’d rather implement the syncing process… the good part is that you could use a websocket connection, so in the desktop app you always use local data and as soon as internet is available, you sync stuff. there is a elixir client for phoenix channels slipstream

edit: i remember a library to replicate a sqlite database using websocket, but i’m not 100% on how it would work

I remember there was a demo on how this exact same thing is done in scenic. I am not sure how easy this is achievable with the mix of js+css+html in elixir-desktop, however in scenic the great thing is declarative UI graphs that are just plain data.

Thanks for your replies.

I saw partisan but I think the concerns about security are what kills my idea. After investigating a bit I see that distributed erlang simply isn’t build for this approach. Slipstream seems like a great solution for implementing that kind of synchronization.

Additionally I guess you could still reuse the most part of the code to build both the server and the desktop application.

1 Like

I think you might be looking for “local-first” software. Many of these are based on CRDT replication. An elixir based one is https://electric-sql.com/

Also, a recent talk:

1 Like

Hey @tj0, author of elixir-desktop here. “local-frist” was also my initial read your the question:

For a local first application there are many ways to sync data with others but two obvious ones are:

  1. Star topology with a single server somewhere
  2. Peer-To-Peer mesh topology without any centralized servers

Using standard Elixir tooling (and elixir-desktop) it is really easy to archive 1. - You can have your local copy of the data that is needed when the client is not connected in a local SQLite database, this is also what the desktop-example-app is doing and then when you’re connected you can call your server API to fetch new data or upload data.

For 2. which is definitely more involved we (my company) developed an elixir library that allows creating end-to-end encrypted connections between any two peers on the internet. GitHub - diodechain/diode_client_ex: Elixir SDK for the diode network it’s pretty low level and exposes raw :ssl streams. So I can’t really recommend this for high productivity at the moment.

CRDTs are probably the future here, especially for mesh networks but from the top of my head I’m not aware of a library that I could point you to there.

Hope this helps a bit,
Cheers!

1 Like