Phineas

Phineas

Best way to logically map IDs to nodes & processes in a distributed Erlang cluster, fast?

Hey everyone,

So I’ve been thinking about this problem for a while now, and can’t think of the best way to solve it.

I basically have resource IDs (Snowflakes) which will run on single GenServers. I have multiple types of resources - users and groups, which run on different Elixir codebases but will still be connected within an Erlang cluster.

Each group will run on it’s own GenServer, but it’s dynamic. The group GenServer will only run if users that are in that specific group are online the service. For example, when a user GenServer starts it’ll grab the groups that user is in from a DB and it’ll need to query some registry to get the PID running each group and call each GenServer to connect to it (group GenServer will just store a list of the PIDs connected). If that registry finds that the group isn’t already online, it’ll need to start that GenServer, then send the PID down back as a reply to the service that called the registry. Remember that this needs to all be done in a distributed Erlang cluster.

Then, when an event happens within that group (e.g. message send) it’ll fan out the message to the user GenServers which will send it to the users down a websocket.

Now, here’s where the problem I’m having comes into play. Messages can be sent from external services, written in different languages - for example, the API, which is written in JS on Node will need to tell the Elixir group GenServer corresponding to the ID that the message was sent to a group, probably via RabbitMQ somehow, but the thing is - the API won’t be able to find the PID of that group because it has no logical map to it.

I know there’s hash rings which are stateless, but I’m not sure how to write a hash function correctly, and even still, wouldn’t that mean that some nodes could run a different amount of groups without knowing, since only the ID would be hashed?

At the moment, my only solution to this is to create some sort of dictionary service in Elixir which stores an ETS table of every single ID and corresponding node & PID linked to that ID. Then, it can listen to RabbitMQ messages for when the API wants to send a message to a specific resource ID and it can forward the message on by looking up the PID/node in the ETS table and sending it a message. Then, the user service can also use this dictionary service when initializing, it can check group PIDs by querying this service, and if the group GenServer isn’t started then the dictionary service can start it and respond back with the corresponding PID.

Sorry if this is super long, it’s really hard to explain properly what I’m trying to do. Please let me know if you have any questions, as some things might be unclear. I’d love to know what you think the best solution would be, and if I’m thinking about hash rings correctly.

Thanks for the help in advance!

Most Liked

jeremyjh

jeremyjh

Have you looked at Horde? Seems promising to me for this kind of use case.

Where Next?

Popular in Questions Top

openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
Phillipp
Hey, I have a NanoPi-M3 and try to install Elixir on their Ubuntu image. I followed the Raspberry Pi installation instructions from the ...
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
mathew4509
I have a list say x = ["23gh", "56kh", "97mh"] I would like to pass each element to Val in each iteration. Say, in iteration 1 -------...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
sabri
Can someone explain the settings of pool_size of Ecto in config file? and what is the recommend size? Thanks
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

Other popular topics Top

Tee
can someone please explain to me how Enum.reduce works with maps
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 27727 240
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New

We're in Beta

About us Mission Statement