Search code examples
elixirerlang-otp

Single application-wide process to be accessed by child processes


I'm writing an Elixir application where some of the processes that access the database will be generating unique identifiers for records that get inserted.

I'm using the CUID library which will let me generate an id in the following way:

{:ok, pid} = Cuid.start_link
Cuid.generate(pid)  # => ch72gsb320000udocl363eofy

Here is how my app is setup

  • There is a phoenix controller which handles a request
  • This controller calls out to my custom Repo.insert command which is currently synchronous
  • Repo.insert calls Cuid.start_link and Cuid.generate every time

Creating a new Cuid process each time feels wrong to me, especially considering that the Cuid lib maintains a counter in its state.

How can different processes within my application send Cuid.generate to the same process?

Thanks!


Solution

  • You could start it up as a supervised and registered worker in your application:

    defmodule MyApp do
      use Application
    
      def start(_type, _args) do
        import Supervisor.Spec, warn: false
    
        children = [
          # Start the endpoint when the application starts
          supervisor(MyApp.Endpoint, []),
          # Start the Ecto repository
          worker(MyApp.Repo, []),
          worker(Cuid, [], [name: :cuid])
        ]
    
        opts = [strategy: :one_for_one, name: MyApp.Supervisor]
        Supervisor.start_link(children, opts)
      end
    
      ...
    end
    

    And then use it in your application like:

    cuid = Cuid.generate(:cuid)