In my erlang application I am trying to follow an approach similar to the one shown in the following part of the documentation, related to simple_one_for_one supervisors: https://www.erlang.org/doc/design_principles/sup_princ#simplified-one_for_one-supervisors . In my case I have a top level supervisor that launches the following one:
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init([]) ->
MaxRestarts = 10,
MaxSecondsBetweenRestarts = 3600,
SupFlags = #{strategy => simple_one_for_one,
intensity => MaxRestarts,
period => MaxSecondsBetweenRestarts},
ChildSpecs = [
#{
id => erws_auction_server,
start => {erws_auction_server, start_link, []},
restart => transient,
shutdown => 2000,
type => worker,
modules => [erws_auction_server]
}
],
{ok, {SupFlags, ChildSpecs}}.
From the documentation, with this kind of strategy no child is created at first, and this is the behavior I need, since I want to dynamically create child processes, that have to execute a function called auction_handle, that needs as argument 4 values (I passed them as a tuple). I defined a function to call the auction_handle with the parameters needed.
%%% Function to start an auction process
start_auction_process({PhoneName, MinimumPrice, AuctionTime, EndDate}) ->
case supervisor:start_child(?MODULE,
[{PhoneName, MinimumPrice, AuctionTime, EndDate}]
) of
{ok, AuctionPid} ->
logger:info("[erws_dynamic_sup] start_auction_process => Start child executed correctly, PID: ~p~n", [AuctionPid]),
AuctionPid;
Error ->
logger:info("[erws_dynamic_sup] start_auction_process => Error: ~p~n", [Error]),
Error
end.
Regarding the function that I have to call, I am trying to include it in a gen_server module that is the following:
start_link(_Args) ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [_Args], []).
init([_Args]) ->
erws_dynamic_sup:start_auction_process(_Args),
{ok, []}.
auction_handle({Phone, Bid, AuctionTime, EndDate}) ->
erws_mnesia:save_auction(Phone, self()),
auction_receive(Phone, Bid, AuctionTime, EndDate).
auction_receive(Phone, Bid, AuctionTime, EndDate) ->
receive
{bidder_join, PhoneName} ->
RemainingTime = get_time_remaining(EndDate),
CurrentWinner = erws_mnesia:get_winner_bidder(PhoneName),
case CurrentWinner of
{WinnerEmail, _} ->
gproc:send({p, l, {?MODULE, PhoneName}}, {joined, Bid, RemainingTime, WinnerEmail});
not_found ->
gproc:send({p, l, {?MODULE, PhoneName}}, {joined, Bid, RemainingTime, []})
end,
auction_handle(Phone, Bid, EndDate - erlang:system_time(second), EndDate);
... other cases
end.
I don’t know how to structure the gen_server in order to be able to call the function I need correctly. I can’t insert the parameters already in the supervisor definition, since I will obtain them later, so for now I passed an empty list in the definition (since simple_one_for_one supervisors shouldn’t start child processes after the definition). Then I added them in the call to start_auction_process made by the gen_server.
What am I doing wrong? I don’t get any error now but the processes does not seem to be launched.