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

nx nx@REDACTED
Fri Feb 27 17:18:39 CET 2015


Oh this is excellent! Thanks! So basically I just have a gen_server
that holds the two pids. If one pid dies the wrapper dies and gets
restarted by the supervisor. That is a lot simpler than I thought!

On Fri, Feb 27, 2015 at 10:17 AM, Christopher Phillips
<lostcolony@REDACTED> wrote:
> 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
>> >
>
>



More information about the erlang-questions mailing list