简体   繁体   English

从erlang流程获取响应

[英]Getting responses from erlang processes

I have an erlang project that makes a lot of concurrent SOAP requests to my application. 我有一个erlang项目,它向我的应用程序发出很多并发的SOAP请求。 Currently, it's limited by how many nodes are available, but I would like to adjust it so that each node can send more than one message at a time. 当前,它受可用节点数的限制,但是我想对其进行调整,以便每个节点一次可以发送多个消息。

I've figured that problem out, but I don't know how to get a response back from process running the SOAP request. 我已经解决了这个问题,但是我不知道如何从运行SOAP请求的进程中获取响应。

This is my function that I'm attempting to use to do multiple threads: 这是我尝试用于执行多个线程的函数:

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).

This function gets called by the person who initiated the stress tester, it is called on every node in our network. 发起压力测试器的人员将调用此函数,该函数将在我们网络中的每个节点上调用。 It's called continually until all the requested number of SOAP requests have been sent and timed. 一直调用它,直到所有请求数量的SOAP请求已发送并计时。

This is the attack_thread that is sent the message by the batch method: 这是通过批处理方法发送消息的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

As you can see, I want it to return the number of seconds the SOAP request took. 如您所见,我希望它返回SOAP请求花费的秒数。 However, erlang's message passing ( Pid ! Message ) doesn't return anything useful. 但是,erlang的消息传递( Pid ! Message )不会返回任何有用的信息。

How can I get a result back? 如何获得结果?

Each of your attack_thread() threads can simply drop a message in the mailbox of the process operating the batch/3 function: 您的每个attack_thread()线程都可以简单地在运行batch/3函数的进程的邮箱中添加一条消息:

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

but then you need to collect the results: 但随后您需要收集结果:

 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.

Some other comments: you probably want spawn_link/1 here. 其他一些评论:您可能在这里想要spawn_link / 1。 If something dies along the way, you want the whole thing to die. 如果一路上有东西死亡,那么您希望整个事情都死掉。 Also, be sure to tune inets httpc a bit so it is more effective. 另外,请确保对inets httpc进行一些调整,以使其更有效。 You might also want to look at basho_bench or tsung. 您可能还需要查看basho_bench或tsung。

Finally, you can use a closure directly rather than pass the url and message: 最后,您可以直接使用闭包,而不用传递url和消息:

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

So your spawn is: 因此,您的生成是:

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

It avoids passing in the message in the beginning. 它避免在开始时传递消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM