arjan / singleton

Global, supervised singleton processes for Elixir
MIT License
108 stars 19 forks source link

Killing parent process? #14

Open jclement opened 8 months ago

jclement commented 8 months ago

Hi there,

This library seems like what I'm looking for, but I'm seeing similar behaviour to what is described in the announcement post on Elixir Forums >> https://elixirforum.com/t/singleton-global-supervised-singleton-processes-for-elixir/2175/3

When a 2nd node joins the cluster, I do see:

23:24:54.246 [info] global: Name conflict terminating {:singleton, #PID<18487.303.0>} But what is unexpected is that not only the singleton process is terminated, but the whole application on one of the nodes:

23:25:47.517 [info] Application wpc5_singleton exited: killed And one of the nodes basically is left in a state where my own application is not running, only the “libraries” continue running.

I have a Phoenix application running across multiple nodes, and I want this Singleton process to run on a single node and be used by all nodes. However, I see that the only node that says running is the one running the Singleton process.

defmodule Pento.Application do
  use Application
  @impl true
  def start(_type, _args) do
    children = [
      PentoWeb.Telemetry,
      Pento.Repo,
      {DNSCluster, query: Application.get_env(:pento, :dns_cluster_query) || :ignore},
      {Phoenix.PubSub, name: Pento.PubSub},
      # Start the Finch HTTP client for sending emails
      {Finch, name: Pento.Finch},
      {Singleton.Supervisor, name: Pento.Singleton},
      # Start to serve requests, typically the last entry
      PentoWeb.Endpoint,
    ]

    opts = [strategy: :one_for_one, name: Pento.Supervisor]
    Supervisor.start_link(children, opts)

    # start singleton service for the global click counter
    Singleton.start_child(Pento.Singleton, Pento.Guesses.CounterServer, [], Pento.Guesses.CounterServer)

  end

...
end
RodolfoSilva commented 7 months ago

@jclement have you tried putting Singleton.Supervisor as the last children?

Abdallahj94 commented 4 months ago

@jclement have you managed to solve this? we're facing the same issue

vhyza commented 2 months ago

Hello @jclement and @Abdallahj94,

I think the reason could be that Application.start callback expects the return value to be {:ok, pid} of the top supervisor.

In the example above the Singleton {:ok, pid} is returned instead. It seems that changing the code to return the app supervisor pid resolves the issue.


defmodule Pento.Application do
  use Application
  @impl true
  def start(_type, _args) do
    children = [
      PentoWeb.Telemetry,
      Pento.Repo,
      {DNSCluster, query: Application.get_env(:pento, :dns_cluster_query) || :ignore},
      {Phoenix.PubSub, name: Pento.PubSub},
      # Start the Finch HTTP client for sending emails
      {Finch, name: Pento.Finch},
      {Singleton.Supervisor, name: Pento.Singleton},
      # Start to serve requests, typically the last entry
      PentoWeb.Endpoint,
    ]

    opts = [strategy: :one_for_one, name: Pento.Supervisor]

    app_supervisor = Supervisor.start_link(children, opts)
    Singleton.start_child(Pento.Singleton, Pento.Guesses.CounterServer, [], Pento.Guesses.CounterServer)
    app_supervisor
  end
...
end