2012-05-14 3 views
0

У меня есть проект erlang, который делает много одновременных запросов SOAP для моего приложения. В настоящее время он ограничен количеством узлов, но я хотел бы настроить его так, чтобы каждый узел мог отправлять более одного сообщения за раз.Получение ответов от процессов erlang

Я понял эту проблему, но я не знаю, как получить ответ от процесса, выполняющего запрос SOAP.

Это моя функция, что я пытаюсь использовать, чтобы сделать несколько потоков:

batch(Url, Message, BatchSize) -> 
    inets:start(), 

    Threads = for(1, BatchSize, fun() -> spawn(fun() -> attack_thread() end) end), 
    lists:map(fun(Pid) -> Pid ! {Url, Message, self()} end, Threads). 

Эта функция вызывается человеком, который инициировал стресс тестером, он вызывается на каждом узле в нашей сети. Он вызывается постоянно, пока не будет отправлено и синхронизировано все запрошенные количества запросов SOAP.

Это attack_thread, который посылается сообщение с помощью метода пакетной:

attack_thread() -> 
receive 
    {Url, Message, FromPID} -> 
     {TimeTaken, {ok, {{_, 200, _}, _, _}}} = timer:tc(httpc, request, [post, {Url, [{"connection", "close"}, {"charset", "utf-8"}], "text/xml", Message}, [], []]), 
     TimeTaken/1000/1000. 
end 

Как вы можете видеть, я хочу, чтобы вернуть количество секунд запрос SOAP взял. Однако передача сообщения erlang (Pid ! Message) не возвращает ничего полезного.

Как я могу получить результат?

ответ

1

Каждый из ваших attack_thread() нитей может просто удалить сообщение в почтовом ящике процесса эксплуатации batch/3 функции:

FromPid ! {time_taken, self(), TimeTaken/1000/1000}. 

, но тогда вам необходимо собрать результаты:

batch(Url, Message, BatchSize) -> 
    inets:start(), 

    Pids = [spawn_link(fun attack_thread/0) || _ <- lists:seq(1, BatchSize], 
    [Pid ! {Url, Message, self()} || Pid <- Pids], 
    collect(Pids). 

collect([]) -> []; 
collect(Pids) -> 
    receive 
    {time_taken, P, Time} -> 
     [Time | collect(Pids -- [P])] 
    end. 

Некоторые другие комментарии: вы, вероятно, хотите здесь spawn_link/1. Если что-то умирает по пути, вы хотите, чтобы все это умерло. Кроме того, обязательно настройте inets httpc немного, чтобы он стал более эффективным. Вы также можете посмотреть на basho_bench или tsung.

Наконец, вы можете использовать замыкание напрямую, а не передавать URL и сообщение:

attack_thread(Url, Message, From) -> ... 

Так что ваш плодиться:

Self = self(), 
Pids = [spawn_link(fun() -> attack_thread(Url, Message, Self) end) || _ <- ...] 

Он избегает проходящее в сообщении в начале.

+0

Я нашел это примерно за час до вашего ответа, я сделал это несколько иначе, но ваш ответ тоже сработает. – Malfist

Смежные вопросы