I have the following Application module and start function:
def start(_type, _args) do
children = [
{
Plug.Cowboy,
scheme: :http,
plug: MyApp,
options: [port: AppConfig.get_port()]},
Repo
]
opts = [strategy: :one_for_one, name: __MODULE__]
Supervisor.start_link(children, opts)
end
end
But when :observer.start method is called to show the nodes and applications I got the following image:
As you can see the module Repo is shown with a name (Elixir.Repo), but the process <0.274.0> never takes a name which is the plug server.
Does someone know how to set a name to a plugSever?
hst337
December 14, 2022, 9:44pm
2
First of all, fix the indentation
def start(_type, _args) do
children = [
{
Plug.Cowboy,
[
scheme: :http,
plug: MyApp,
options: [port: AppConfig.get_port()
]
},
Repo
]
opts = [strategy: :one_for_one, name: __MODULE__]
Supervisor.start_link(children, opts)
end
Second, to set a name for the process, use Process.register/2
, but
Unless you want to reference the process by name in the code, it is useless
You’ll need to set a name for the process each time it starts
Thanks so much, Hisssst, I will read about Process. register.
al2o3cr
December 15, 2022, 1:04am
4
Can you describe what you’re hoping to do with that name, were it possible to set it?
The unnamed process that’s started is configured via Plug.Cowboy.child_spec
:
case :ranch.child_spec(ref, ranch_module, transport_opts, cowboy_protocol, proto_opts) do
{id, start, restart, shutdown, type, modules} ->
%{
id: id,
start: start,
restart: restart,
shutdown: shutdown,
type: type,
modules: modules
}
child_spec when is_map(child_spec) ->
child_spec
end
which turns the supplied options into options for :ranch.child_spec
. That function returns a configuration that starts a supervisor using ranch_embedded_sup
:
-spec child_spec(ref(), module(), opts(), module(), any())
-> supervisor:child_spec().
child_spec(Ref, Transport, TransOpts0, Protocol, ProtoOpts) ->
TransOpts = normalize_opts(TransOpts0),
#{id => {ranch_embedded_sup, Ref}, start => {ranch_embedded_sup, start_link, [
Ref, Transport, TransOpts, Protocol, ProtoOpts
]}, type => supervisor}.
ranch_embedded_sup
is the module that’s running in <0.274.0>
there. It’s a minimal Supervisor, with two children:
start_link(Ref, Transport, TransOpts, Protocol, ProtoOpts) ->
supervisor:start_link(?MODULE, {Ref, Transport, TransOpts, Protocol, ProtoOpts}).
-spec init({ranch:ref(), module(), any(), module(), any()})
-> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}.
init({Ref, Transport, TransOpts, Protocol, ProtoOpts}) ->
Proxy = #{id => ranch_server_proxy,
start => {ranch_server_proxy, start_link, []},
shutdown => brutal_kill},
Listener = #{id => {ranch_listener_sup, Ref},
start => {ranch_listener_sup, start_link, [Ref, Transport, TransOpts, Protocol, ProtoOpts]},
type => supervisor},
{ok, {#{strategy => rest_for_one}, [Proxy, Listener]}}.
All of the functions to manipulate listeners in :ranch
use the ref
term supplied to :ranch.child_spec
to identify which listener, for instance :ranch.set_max_connections/2
:
set_max_connections(Ref :: ranch:ref(),
MaxConns :: ranch:max_conns())
-> ok
Plug.Cowboy
accepts a ref
option, or it uses a default of the plug module + scheme, so MyApp.HTTP
in your example.
Hi al2o3cr, thank you so much for the awesome explanation,
I am a newcomer in Elixir, I made a test project using a supervisor like this :
is for tracking purposes, for example, I would like to get something like this:
If I have a memory problem with a process, I want to get the possibility to know what the process is.
but if I cannot label it, I will see only a number as is shown in the following image:
You can always get it from the top supervisor and assign it to a variable. Obviously this is for debugging purposes.
top_level_processes = Supervisor.which_children(BankingService.Supervisor)
[web | _] = top_level_processes # refine this part