How to run more then one same worker (Cachex) inside Supervision

Hi, I’m trying to add inside my application supervision tree two of Cachex (https://hexdocs.pm/cachex/Cachex.html) worker but getting error:

** bad child specification, more than one child specification has the id: Cachex. **

code :
children = [

worker(Cachex, [:requests, [] ]),
worker(Cachex, [:ntf, [] ])
]

As error text suggesting using to use maps as child specifications, i changed code to look like this:

children = [
Supervisor.child_spec({Cachex, [:requests, []]}, id: :my_cache_1),
Supervisor.child_spec({Cachex, [:ntf, []]}, id: :my_cache_2)
]

but now getting ** (EXIT) :invalid_name **
I wonder if there is any way to make it work or if some one more familiar with this library and can help me.

Thanks!

This:

{Cachex, [:requests, []]}

means the supervisor will call Cachex.start_link/1 like this:

Cachex.start_link([:requests, []])

rather than Cachex.start_link/2, which is probably what you expected:

Cachex.start_link(:requests, [])

So passing {Cachex, :requests} instead should work, because it’ll call Cachex.start_link(:requests).

If you want to pass options later on you’ll have to set the start function in the child spec yourself to make sure it calls start_link/2 and not start_link/1.

For context, recent Elixir guidelines are to always use start_link/1, so it’s normally not a problem. Cachex probably predates that.

3 Likes

I see, many thanks!
I will try once get home.

Just in case some one need to see code for implementation:

def start(_type, _args) do
  import Supervisor.Spec
  import Cachex.Spec

  children = [
      %{id: Cache1, start: {Cachex, :start_link, [:requests, []]}},
      %{id: Cache2, start: {Cachex, :start_link, [:messages, []]}}
    ]
  opts = [strategy: :one_for_one]
  Supervisor.start_link(children, opts)
end
6 Likes