Question

What is the most recommended way in Erlang to ensure that some process exists before sending a message / event to it? In my scenario I am starting process upon first occurrence of the message and then it stays alive. While keep passing further messages, I first try to start the process with the same name to ensure it is started, something like this (using gen_fsm and simple-one-for-one restart scenario):

%% DeviceId - process name

heartbeat(ApplicationKey, DeviceId, Timeout) ->
    ensure_session_started(ApplicationKey, DeviceId, Timeout),
    gen_fsm:send_event(DeviceId, {heartbeat, Timeout}).

ensure_session_started(ApplicationKey, DeviceId, Timeout) ->
    case session_server_sup:start_child(ApplicationKey, DeviceId, Timeout) of
        {ok, _Pid} -> {ok, running};
        {error, {already_started, _}} -> {ok, running};
        {error, Error} -> erlang:throw({error, {failed_to_start_session, Error}})
    end.

I believe this solution is not perfect and probably has some overhead but still believe it is less race condition prone than using erlang:is_process_alive. Am I right? Any ideas how to improve it?

Was it helpful?

Solution

You are right, erlang:is_process_alive/1 approach is useless in this scenario because of race condition.

Your example is workable and I saw it in the wild few times. Note that it does not guarantee that message will be processed. To be sure of that you need to monitor your receiver and get confirmation from it. This is how it is done in gen_server:call/2.

OTHER TIPS

With gen_fsm:sync_send_event/2,3 you can send events to your FSM and wait for a response. So you can tell your calling process that its message has been received.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top