So I have a genserver that opens a message server.
defmodule MessageServer do
use GenServer
def start_link(opts \\ []) do
GenServer.start_link(__MODULE__, [], opts)
end
# ... lot more functions
end
So to be able to start this, I have to enter iex and pattern match against MessageServer.start_link(table: messageserver_table) etc.
Can I somehow make this faster? so if I enter iex in this file or generally in this project, its starting that genserver automatically? maybe in the application child, im not sure about it though.
I tried the following:
children = [
MessageServer.start_link()
]
but errored,
21:06:58.812 [notice] Application messageserver exited: exited in: MessageServer.Application.start(:normal, [])
** (EXIT) an exception was raised:
** (ArgumentError) The module :ok was given as a child to a supervisor but it does not exist.
(elixir 1.14.0) lib/supervisor.ex:701: Supervisor.init_child/1
(elixir 1.14.0) lib/enum.ex:1658: Enum.“-map/2-lists^map/1-0-”/2
(elixir 1.14.0) lib/supervisor.ex:687: Supervisor.init/2
(elixir 1.14.0) lib/supervisor.ex:617: Supervisor.start_link/2
(kernel 8.5.2) application_master.erl:293: :application_master.start_it_old/4
** (Mix) Could not start application messageserver: exited in: MessageServer.Application.start(:normal, [])
** (EXIT) an exception was raised:
** (ArgumentError) The module :ok was given as a child to a supervisor but it does not exist.
When you start the genserver without passing name argument, you receive the response in the format of:
# Start the server
{:ok, pid} = GenServer.start_link(Stack, [:hello])
Where the pid is the local identifier you can address your genserver from:
GenServer.call(pid, :hello)
Now when you are starting your genserver from the application supervision, there is no easy way to get that pid, so it is easier to register your genserver with a global name, so you can reference it from iex just by the name you defined.
You actually can by asking the supervisor about it. Your application supervisor will itself have a name like YourApp.Supervisor (check your application.ex file to be sure).
You can do:
Supervisor.which_children(YourApp.Supervisor)
You’ll see a list of tuples, and your genserver will be on that list, along with its pid. You can Enum.find on that list to get the pid.
where do I have to paste that? below the Supervisor.start_link(children, opts)?
I did try that and def start says
The inferred return type of start/2
([{_,
'restarting' | 'undefined' | pid(),
'supervisor' | 'worker',
'dynamic' | [atom()]}]) has nothing in common with
{'error', _} | {'ok', pid()} | {'ok', pid(), _}, which is the expected return type for the callback of the 'Elixir.Application' behaviour
putting it above wont work as it has to start first
If you look at the Name Registration documentation linked to above, you’ll see that there are multiple ways (limitless ways? as you can make your own) to name a process. There are also plenty of cases where you don’t need/want to name them, thus naming a GenServer is optional and how you do so is up to you.
oh cool, yea, I got the following [{Msg.Server, #PID<0.153.0>, :worker, [Msg.Server]}]
how can I automatically connect now? because running iex -S mix does nothing except for starting shell, I have to type everything on my own that takes lot of time xD
If there’s only going to be one Msg.Server and you want to easily send messages to it, then it’s best to name the process and address it that way. As described in Start genserver automatically? - #4 by D4no0