0

アプリケーションに対して多数の同時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)は有用なものを返しません。

どうすれば結果を取り戻すことができますか?

4

1 に答える 1

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が必要です。途中で何かが死んだら、全部死んでほしい。また、より効果的になるように、inetshttpcを少し調整してください。また、basho_benchまたはtsungも確認することをお勧めします。

最後に、URLとメッセージを渡すのではなく、クロージャーを直接使用できます。

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

つまり、スポーンは次のようになります。

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

最初にメッセージを渡すことを避けます。

于 2012-05-14T17:21:57.140 に答える