在我的 erlang 应用程序中,我有一个顶级主管来监视牛仔服务器(gen_server):
start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
init([]) ->
SupFlags = #{strategy => one_for_one,
intensity => 5,
period => 30},
ChildSpecs = [#{id => erws_server,
start => {erws_server, start_link, []},
restart => permanent}],
{ok, {SupFlags, ChildSpecs}}.`
对服务器的请求可以触发另一个模块(称为 erws_auction_agent)的函数调用。在这个模块中,当收到某个请求时,它会生成一个必须处理该请求的新进程(在本例中是拍卖):
AuctionPid = spawn(fun() -> auction_handle(PhoneName, MinimumPrice, AuctionTime, EndDate) end)
auction_handle函数基本上必须等待erlang消息并根据消息执行不同的操作:
auction_handle(Phone, Bid, AuctionTime, EndDate) ->
receive
%% Receive JOIN request from a Bidder
{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.
我认为为这些动态添加的流程配备一个主管可能是个好主意。我尝试将它们添加到已经存在的主管中,并从更高级别的主管开始创建另一个主管,但遇到了与子规范相关的相同错误。例如,我尝试通过调用以下函数将孩子添加到顶级主管:
start_auction_process(PhoneName, MinimumPrice, AuctionTime, EndDate) ->
{ok, AuctionPid} = supervisor:start_child(?SERVER,
[#{id => PhoneName,
start => {erws_auction_agent, auction_handle, [PhoneName, MinimumPrice, AuctionTime, EndDate]},
restart => transient}]),
AuctionPid.
我得到的错误如下:
{error,
{invalid_child_spec,
[#{id => <<"Sony Xperia Pro">>, restart => transient,
start =>
{erws_auction_agent,auction_handle,
[<<"Sony Xperia Pro">>, 1, 240,
1714667160]}}]}}
我做错了什么?在这种情况下,哪种方法最好使用?我是否需要有一个单独的 gen_server 用于处理拍卖逻辑?预先感谢。
这个:
start_auction_process(PhoneName, MinimumPrice, AuctionTime, EndDate) ->
{ok, AuctionPid} = supervisor:start_child(?SERVER,
[#{id => PhoneName,
start => {erws_auction_agent, auction_handle, [PhoneName, MinimumPrice, AuctionTime, EndDate]},
restart => transient}]),
应该是:
start_auction_process(PhoneName, MinimumPrice, AuctionTime, EndDate) ->
{ok, AuctionPid} = supervisor:start_child(?SERVER,
#{id => PhoneName,
start => {erws_auction_agent, auction_handle, [PhoneName, MinimumPrice, AuctionTime, EndDate]},
restart => transient}),