Ошибка: неверная спецификация дочернего элемента в функции супервизора start_child

В моем приложении на 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 для логики handle_auction? Заранее спасибо.

Введение в одну из самых важных концепций в React - функциональное программирование
Введение в одну из самых важных концепций в React - функциональное программирование
React разработан с использованием концепции функционального программирования, поэтому понимание функционального программирования важно для изучения...
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Что такое Java 8 Streams API? Java 8 Stream API
1
0
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Supervisor:start_child/2 определяется так:

start_child(SupRef, ChildSpec) -> startchild_ret()

где ChildSpec имеет тип:

child_spec() | (List :: [term()])

И child_spec() определяется как:

   #{stuff in here} OR {stuff in here}

В целом ChildSpec может быть:

#{stuff in here} OR {stuff in here} OR [stuff in here]

Вместо этого:

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
             }
    ),
   

Спасибо! Это была проблема, которая вызвала ошибку valid_child_spec, я видел (List :: [term()]) в определении start_child/2 и предположил, что это тот же самый вариант, который использовался в функции инициализации супервизора, но это было не так. т. е.

Salvatore Lombardi 04.05.2024 17:47

Другие вопросы по теме