GithubHelp home page GithubHelp logo

singleton's Introduction

Singleton

Build Status Module Version Hex Docs Total Download License Last Updated

Convenience wrapper library around Erlang's global module to ensure a single instance of a process is kept running on a cluster of nodes.

Installation

The package can be installed as:

  1. Add singleton to your list of dependencies in mix.exs:
def deps do
  [{:singleton, "~> 1.0"}]
end
  1. Ensure Singleton.Supervisor is added to your application's supervision tree:

If your application includes a supervision tree in application.ex, you can simply add Singleton.Supervisor to the list of children.

children = [
  # ...,
  {Singleton.Supervisor, name: MyApp.Singleton}
]

supervisor = Supervisor.start_link(children, opts)

Usage

Use Singleton.start_child/4 to start a unique GenServer process.

Singleton.start_child(MyApp.Singleton, MyServer, [1], {:myserver, 1})

Execute this command on all nodes. The MyServer GenServer is now globally registered under the name {:global, {:myserver, 1}}.

As soon as you connect nodes together, you'll see logger messages like:

04:56:29.003 [info]  global: Name conflict terminating {MyServer, #PID<12501.68.0>}

When you now stop (or disconnect) the node on which the singleton process runs, you'll see it get started on one of the other nodes.

Troubleshooting

More than 3 singleton processes [info] Application singleton exited: shutdown

In case you run more than 3 singleton you'll need to increase the max_restarts of DynamicSupervisor.

config :singleton,
  dynamic_supervisor: [max_restarts: 100]

or add max_restarts to your singleton supervisor spec:

  {Singleton.Supervisor, name: MyApp.Singleton, max_restarts: 100}

singleton's People

Contributors

arjan avatar ericdude4 avatar klacointe avatar juulsme avatar wkirschbaum avatar pziaugra avatar

Stargazers

Adriano Santos avatar Kenley Tomlin avatar Bastien Penavayre avatar Nicholas Moen avatar Chanphirom Sok avatar Dmitry Shpagin avatar Niranjan Anandkumar avatar  avatar Jean-Louis Huynen avatar Bruno Malvestuto avatar Nicolas Mena avatar  avatar Marcin Kulik avatar Fritz Blueford avatar Simon Hansen avatar Parker Hewitt avatar Giorgio Azzinnaro avatar Roberto Ribeiro avatar marcos ferreira avatar Steffen Deusch avatar Jonadabe Nascimento avatar Guilherme Oliveira avatar Erik van der Wal avatar Jinkyou Son avatar Simon Escobar Benitez avatar Carlo Gilmar avatar Felipe Menegazzi avatar Andrew Chou avatar Gal Schlezinger avatar Mathew Garland avatar TavernGoal avatar Ben Coppock avatar  avatar Mads Schou avatar George Lima avatar John Barker avatar Trevor Owens avatar Rodney Folz avatar David Skoog avatar guru.arumugam avatar  avatar Blake Dietz avatar Mihai Târnovan avatar  avatar Tanjim Hossain avatar Sam Gaw avatar Ahto Jussila avatar Josiah Witt avatar ChanYub Park avatar john invictus avatar Dmitry Ledentsov avatar Tanapat Xu avatar Myroslav Kiurchev avatar Shriniwas Sharma avatar David White avatar andrey pechorin avatar Mikal avatar James Stephens avatar Jared Mackey avatar Sava Vranešević avatar Danil Karpov avatar Adam Eury avatar Adam Oswalt avatar Matteo Cafasso avatar Aleksander avatar Sheharyar Naseer avatar Gabriel Cueto avatar tt67wq avatar Qiu Hua avatar Sérgio Hilgert avatar Aki Wu avatar Jason Cheung avatar Henricus Louwhoff avatar Tristan NGUYEN avatar Martin Holman avatar Christian Meunier avatar Alex Castaño avatar Dennis Ideler avatar Nitin Misra avatar Roman Heinrich avatar Phillipp Ohlandt avatar László Bácsi avatar Leonel Mendez Jimenez avatar Lucas Polonio avatar Jordan Piepkow avatar Brian Howenstein avatar Thúlio Costa avatar Erik Nilsen avatar Marlus Saraiva avatar Paulo Suzart avatar Óscar de Arriba avatar Ricardo García Vega avatar GoFOSS.IO avatar Eric Zhang avatar Źmićer Rubinštejn avatar Lucas Alves avatar Eugene avatar Steven Livingstone-Perez avatar Mads Hargreave avatar Barry Hoggard avatar

Watchers

 avatar James Cloos avatar  avatar

singleton's Issues

Killing parent process?

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

Possible change in manager process

It is possible that this line

use GenServer, restart: :transient

is the one that make managers process not to be restarted, when normal shutdown of process used in singleton?

when scaling down one service, my single process gets down and doesn't get up in remaining nodes of service... I think is because it gets detected as normal shutdown instead of abruptly

https://hexdocs.pm/elixir/Supervisor.html#module-restart-values-restart

If so, would be nice to pass the restart value by config, when starting the singleton

Incompatibility with Elixir 1.10.0 – Singleton.start_child uses deprecated args

Using singleton 1.2.0, In the latest stable elixir release, 1.10.0, Supervisor.start_child/2 doesn't expect a list as a second arg: elixir-lang/elixir@98e60a8

In the code I call Singleton.start_child, dialyzer fails:

  # {{…}}
  def start_link(_opts) do
    Singleton.start_child(__MODULE__, [], __MODULE__)
  end
  # {{…}}
lib/{{…}}/scheduler.ex:7:no_return
Function start_link/1 has no local return.
________________________________________________________________________________
done (warnings were emitted)
Halting VM with exit status 2

Ability to execute custom start_link

https://github.com/arjan/singleton/blob/master/lib/singleton/manager.ex#L58

  defp restart(state) do
    start_result =
      GenServer.start_link(state.mod, state.args, name: {:global, state.name})

    pid =
      case start_result do
        {:ok, pid} ->
          pid

        {:error, {:already_started, pid}} ->
          state.on_conflict && state.on_conflict.()
          pid
      end

    Process.monitor(pid)
    %State{state | pid: pid}
  end

It would be nice if GenServer.start_link/3 here could be replaced by state.mod.start_link/3. That would allow for starting a process which depends on custom code within the start_link/3 function.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.