csokun

csokun

Call Horde.Registry.put_meta inside terminate/2 doesn't persist state

Hi, I’m trying to understand how to properly implement GenServer state handoff in a cluster environment.

I searched around and managed to get a simple GenServer up & running elixir_libcluster_horde_demo/lib/mix_app1/greeting.ex at main · csokun/elixir_libcluster_horde_demo · GitHub using libcluster & horde.

Based on my reading, I should be able to perform state handoff by simply:

  • Add Process.flag(:trap_exit, true) in init/2
  • Persist state via terminate/2, using Horde.Registry.put_meta/3
  • Reload existing state on init/2 or handle_continue/2 using Horde.Registry.meta/2

Each time I kill the old process using :init.stop() a new process is successfully spawned on another node. However, the newly spawned process is unable to find the existing state calling Horde.Registry.meta(...) always return :error

But, if I manually invoke Horde.Registry.put_meta(...) then :init.stop() the newly spawned process can restore the state.

Is there something wrong with my implementation? Why calling Horde.Registry.put_meta(...) within terminate/2 does not save the GenServer state.

Most Liked

derekkraan

derekkraan

Hi, sorry for taking so long to respond, Horde’s backing store (DeltaCRDT) is eventually-consistent, and there is no mechanism for checking to see if the locally-applied changes have been synced.

Using Horde.Registry.put_meta/3 during shutdown is unlikely to work well, as @hubertlepicki has pointed out, since syncing is performed asynchronously, and since you’re in the process of shutting down the node, it’s highly likely that the node will stop before any syncing can happen.

My recommendation for now, as Horde is not persisted, would be to only use Horde for data that you can afford to lose. Process state handoff would be better implemented using a database like Postgres or Redis, or perhaps something else.

hubertlepicki

hubertlepicki

I strongly suspect what is happening here is that you’re shutting down the whole node before Horde.Registry manages to propagate its state across other nodes in the cluster. CRDTs are eventually consistent and it’s not an immediate changes that you’re putting onto registry, they have to be synced back to the rest of the cluster.

I never did what you’re trying to do, with using Horde to pass the state to itself so not sure how to handle it and if it’s good idea at all.

What I found a reliable way to pass the state in the above situation, and also to ensure that a required process indeed starts on the other nodes was to use PostgreSQL to store the state. In my case there were two scenarios: one in which I scheduled an Oban job to start a corresponding process on other nodes, and in it’s payload I was passing the state, in another case I was just saving the state to a database and process would be started on-demand on other nodes when required and would pick it up.

anuaralfetahe

anuaralfetahe

I believe using Process.sleep is not a very reliable option since the distribution of state may take longer or less due to the underlying network. I typically address similar cases using message passing.

Where Next?

Popular in Questions Top

_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
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
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
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
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

Other popular topics Top

AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
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
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
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement