Reputation: 714
So I am having trouble following this "super simple" example. New to Elixir(From a Ruby background predominantly).
Just trying to create a pool of redis connections setup under the main application supervision tree to use for active user sessions but in truth redis is going to be a lot more useful down the line so I am trying to get this setup right.
This line:
start: {Supervisor, :start_link, [children_redix]}
Gives me the following error:
** (Mix) Could not start application gametime:
Gametime.Application.start(:normal, []) returned an error: shutdown:
failed to start child: RedixSupervisor
** (EXIT) an exception was raised:
** (UndefinedFunctionError) function Supervisor.start_link/1 is undefined or private
(elixir) Supervisor.start_link([%{id: {Redix, 0}, start: {Redix, :start_link, [[name: :redix_0]]}, type: :worker}, %{id: {Redix, 1}, start: {Redix, :start_link, [[name: :redix_1]]}, type: :worker}, %{id: {Redix, 2}, start: {Redix, :start_link, [[name: :redix_2]]}, type: :worker}, %{id: {Redix, 3}, start: {Redix, :start_link, [[name: :redix_3]]}, type: :worker}, %{id: {Redix, 4}, start: {Redix, :start_link, [[name: :redix_4]]}, type: :worker}])
and if I remove the square brackets from the children_redix on the above line I get:
** (UndefinedFunctionError) function Supervisor.start_link/5 is undefined or private
This is the documentation I am following:
https://hexdocs.pm/redix/real-world-usage.html
This is the application start function:
defmodule Gametime.Application do
use Application
use Supervisor
def start(_type, _args) do
pool_size = 5
#creates redix children processes
children_redix =
for i <- 0..(pool_size - 1) do
Supervisor.child_spec({Redix, name: :"redix_#{i}"}, id: {Redix, i})
end
children = [
# child spec for the supervisor I am trying to add to the main supervision tree,
%{
id: RedixSupervisor,
type: :supervisor,
start: {Supervisor, :start_link, [children_redix]}
},
# This way is now deprecated - although this was generated by phoenix so not going to touch this just yet.
supervisor(Gametime.Repo, []),
supervisor(GametimeWeb.Endpoint, []),
# Start your own worker by calling: Gametime.Worker.start_link(arg1, arg2, arg3)
# worker(Gametime.Worker, [arg1, arg2, arg3]),
]
opts = [strategy: :one_for_one, name: Gametime.Supervisor]
Supervisor.start_link(children, opts)
end
I'm just not sure where I am going wrong. I feel like it may be an assumption being made in the docs as to what I should know - but I don't know what I don't know unfortunately. Any help would be awesome - cheers.
Upvotes: 2
Views: 714
Reputation: 714
oh wow - so I guess the docs are outdated. Went through some pain to figure this out - so thought I would share.
... %{
id: RedixSupervisor,
type: :supervisor,
start: {Supervisor, :start_link, [ children_redix , [strategy: :one_for_one] ]}
}, ...
is the answer. The docs seem to just pass the children_redix
child_spec maps - but this isn't what Supervisor.start_link/2
expects as a signature.
I might be missing more to the story and again there could be something in the how to
that I am not picking up due to a possible assumption of what people should already be aware of.
cheers
Upvotes: 2
Reputation: 2290
You probably need to wrap:
Supervisor.child_spec(%{
id: RedixSupervisor,
type: :supervisor,
start: {RedixSupervisor, :start_link, [children_redix]}
})
And on the start
tuple use your RedixSupervisor
module, and not the generic Supervisor
. From the start_link/1
defined in RedixSupervisor, where you'll receive the arguments (in this case, children_redix
) is where you'll Supervisor.start_link
, and use the children passed as the argument in the init
function
An example would be:
defmodule RedixSupervisor do
use Supervisor
require Logger
def start_link(children_redix) do
Logger.info("RedixSupervisor Start Link")
Supervisor.start_link(__MODULE__, children_redix, name: __MODULE__)
end
def init(children_redix) do
children = children_redix
Supervisor.init(children, strategy: :one_for_one)
end
end
Upvotes: 0