Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Name conflict terminating EventStore.Notifications.Supervisor #181

Closed
slashdotdash opened this issue Nov 12, 2019 · 1 comment
Closed

Name conflict terminating EventStore.Notifications.Supervisor #181

slashdotdash opened this issue Nov 12, 2019 · 1 comment

Comments

@slashdotdash
Copy link
Member

slashdotdash commented Nov 12, 2019

The EventStore.Notifications.Supervisor process is named using :global to ensure only a single instance runs, regardless of how many nodes are connected when using distributed Erlang. This is because there should be only one process listening and publishing events to subscriptions.

When a node joins a cluster there will be a name clash and one process, at random, will be terminated. See register_name/2 in :global docs for details.

This results in error messages on one node due to the exited supervisor process and its children. These messages do not need to be treated as errors.

On Node A:

[info] global: Name conflict terminating {EventStore.Notifications.Supervisor, #PID<15777.550.0>}

On Node B:

[error] GenServer EventStore.Notifications.Listener.Postgrex terminating
** (stop) killed
Last message: {:EXIT, #PID<0.550.0>, :killed}

[error] GenServer EventStore.Notifications.Reader.Postgrex terminating
** (stop) killed
Last message: {:EXIT, #PID<0.550.0>, :killed}

Instead of logging an error it would be preferable to shutdown one of the duplicate processes with a normal exit. :global supports other exit strategies, such as notify instead of exit. Unfortunately Elixir’s use of :global for GenServer name registration doesn’t allow specifying the strategy.

It would be possible to write a wrapper module for forward the calls to :global and also provide the resolve function (using {:via, EventStore.GlobalProxy, name}).

defmodule EventStore.GlobalProxy do
  def register_name(name, pid) do
    :global.register_name(name, pid, &resolve/3)
  end

  defp resolve(name, pid1, pid2) do
    # Shutdown one process to resolve name clash
  end
end
@slashdotdash
Copy link
Member Author

Fixed by #210.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant