错误:主管 start_child 函数中的子规范无效

问题描述 投票:0回答:1

在我的 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 用于处理拍卖逻辑?预先感谢。

functional-programming erlang distributed-computing erlang-otp erlang-supervisor
1个回答
0
投票

这个:

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}),
   
© www.soinside.com 2019 - 2024. All rights reserved.