[erlang-questions] Supervising a Process that is Dependent on Another Process

Christopher Phillips lostcolony@REDACTED
Fri Feb 27 16:17:21 CET 2015


Sort of; you don't need a monitor because they're linked (so any process
deaths will cause a death of the wrapper process, the eredis_sub process,
and the eredis_smart_sub process). Make those calls from within your own
process (maintaining the pid(s) you need in the process state), and
supervise ~that~. If either your process, or either of the two that are
spawned in the example code snippet on that page, die, the link will cause
the other two to also die, your wrapper process to restart, and those two
to reinitialize. Make all your calls through your wrapper process. That is,
something like -

*my_sup.erl

init(_) ->
  MyProcSpec = ...,
  {ok, { {one_for_one, 10, 10}, [MyProcSpec]} .



*my_proc.erl (I'm assuming this is a gen_server)

init(_) ->
  {ok, EredisSubClient} = eredis_sub:start_link(),
  {ok, SubClient} = eredis_smart_sub:start_link(EredisSubClient),
  {ok, [{eredis_sub, EredisSubClient}, {eredis_smart_sub, SubClient}]}.

handle_cast(A, State) ->
   proplists:get_value(eredis_smart_sub, State) ! A,
   ...
  {noreply, State}.

handle_call(A, _, State) ->
   proplists:get_value(eredis_smart_sub, State) ! A,
  ...
  {reply, ..., State}.


etc.

You can also register those pids in my_proc:init, and reference them
externally using whereis(WellKnownName), as I mentioned before, but you'll
likely want to unregister them as part of the terminate  (and in either
case, you need to ensure that this process is up first in your supervisor
hierarchy, before anything that relies on it, likely using rest_for_one, as
mentioned before, so you don't end up sending messages to a pid that
corresponds to nothing).


On Thu, Feb 26, 2015 at 6:29 PM, Chase James <chase.james@REDACTED>
wrote:

> To bring the discussion closer to my problem domain, I'm specifically
> trying to bring the eredis_smart_sub app
> (https://github.com/nacmartin/eredis_smart_sub) under supervision, but
> it requires the Pid of eredis to be passed in to its start_link
> function.
>
> Because of the way its designed, is it safe to say you can't put it
> under supervision directly without a wrapper module that uses the
> registered eredis Pid and creates like a monitor or something for the
> eredis_smart_sub gen_server?
>
> Thanks for your time and advice!
>
> On Wed, Feb 25, 2015 at 11:32 PM, Christopher Phillips
> <lostcolony@REDACTED> wrote:
> >   There are a couple of ways to achieve this, though not directly the way
> > you describe. You would not pass in the Pid into the supervision spec,
> > because the Pid can change any time a process restarts. Instead, you
> need to
> > register the Pid to a name, and use the name.
> >
> >   As a quick aside, it sounds like the second process is dependent on the
> > first process being up. With that in mind, you'll likely want a
> rest_for_one
> > supervision strategy, with the first process being the first in the child
> > spec list.
> >
> >   To your question, most gen_server examples actually are set up to do
> this
> > for you, and you don't generally need the Pid, but if you're not using a
> > gen_server you can manually use erlang:register/2, and erlang:whereis/1
> to
> > register the Pid to an atom, and to look up the Pid, as appropriate.
> >
> >
> >   That is, I can do something like the following for my first process
> > (ellipsis are indicative of 'assume the proper arguments; not relevant to
> > the answer at hand') -
> >
> > start_link() ->
> >   gen_server:start_link({local, NameToRegisterItAs}, ...).
> >
> > or if not using a gen_server,
> >
> > start_link() ->
> >   Pid = spawn_link(...),
> >   true = register(NameToRegisterItAs, Pid),
> >   Pid.
> >
> >
> >
> > and then elsewhere (my second process) where I need that Pid, I can use
> >
> > whereis(NameToRegisterItAs)
> >
> > to get the Pid. As long as you set up your supervisor correctly, and
> > assuming a single node (else you may need to globally register it rather
> > than locally) the registered Pid should always be the one the process is
> > running under.
> >
> >
> >
> >>
> >> ------------------------------
> >>
> >> Message: 7
> >> Date: Wed, 25 Feb 2015 14:03:44 -0500
> >> From: nx <nx@REDACTED>
> >> To: erlang-questions <erlang-questions@REDACTED>
> >> Subject: [erlang-questions] Supervising a Process that is Dependent on
> >>         Another Process
> >> Message-ID:
> >>
> >> <CAP8Yv7KxYS+qXA04k7qWjZMjZMpD9uaMsAOwL2W4yA+6=VZMyw@REDACTED>
> >> Content-Type: text/plain; charset=UTF-8
> >>
> >>
> >> Is it possible to supervise a process that requires the Pid of another
> >> process in its start_link function?
> >>
> >> I'm not clear on how I can get the supervisor to 1) start a process 2)
> >> start another process with the Pid of the first process, then 3)
> >> restart both of these if the first process fails and automatically
> >> pass in the Pid of the restarted first process to the second process.
> >>
> >> I may be expecting too much from the supervisor. Any suggestions?
> >>
> >> Thanks!
> >>
> >>
> >
> > _______________________________________________
> > erlang-questions mailing list
> > erlang-questions@REDACTED
> > http://erlang.org/mailman/listinfo/erlang-questions
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20150227/5801cc88/attachment.htm>


More information about the erlang-questions mailing list