本文介绍了了解赛璐oid并发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是我的赛璐codes代码.

Following are my Celluloid codes.

  1. client1.rb 2个客户端之一. (我将其命名为客户端1)

  1. client1.rb One of the 2 clients. (I named it as client 1)

client2.rb 2个客户端中的第二个. (名为客户端2)

client2.rb 2nd of the 2 clients. (named as client 2 )

注意:

上述两个客户端之间的唯一区别是传递到服务器的文本.即(分别为'client-1''client-2')

Note:

the only the difference between the above 2 clients is the text that is passed to the server. i.e ('client-1' and 'client-2' respectively)

在针对以下2台服务器(一次运行一台)测试这2个客户端(并排运行)时.我发现结果非常奇怪.

On testing this 2 clients (by running them side by side) against following 2 servers (one at time). I found very strange results.

  1. server1.rb (摘自自述文件的基本示例.赛璐ul-zmq的md )

将其用作上述2个客户端的示例服务器导致并行执行任务.

Using this as the example server for the 2 above clients resulted in parallel executions of tasks.

输出

ruby server1.rb

Received at 04:59:39 PM and message is client-1
Going to sleep now
Received at 04:59:52 PM and message is client-2

注意:

client2.rb 消息在 client1.rb 请求处于睡眠状态时得到处理.(并行性标记)

Note:

the client2.rb message was processed when client1.rb request was on sleep.(mark of parallelism)

  1. server2.rb

将其用作上述2个客户端的示例服务器没有导致并行执行任务.

Using this as the example server for the 2 above clients did not resulted in parallel executions of tasks.

输出

ruby server2.rb

Received at 04:55:52 PM and message is client-1
Going to sleep now
Received at 04:56:52 PM and message is client-2

注意:

client-2 被要求等待60秒,因为 client-1 处于睡眠状态(睡眠60秒)

Note:

the client-2 was ask to wait 60 seconds since client-1 was sleeping(60 seconds sleep)

我多次运行以上测试,所有测试均导致相同的行为.

I ran the above test multiple times all resulted in same behaviour.

有人可以从上述测试的结果中解释我吗.

Can anyone explain me from the results of the above tests that.

问题:为什么赛璐ul要等待60秒才能处理其他请求(即在server2.rb情况下已注意到?)?

Question: Why is celluloid made to wait for 60 seconds before it can process the other request i.e as noticed in server2.rb case.?

ruby -v

ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0]

推荐答案

使用您的要点,我验证了此问题可以在MRI 2.2.1以及jRuby 1.7.21Rubinius 2.5.8中重现.... 和server2.rb是后者中DisplayMessagemessage类方法的使用.

Using your gists, I verified this issue can be reproduced in MRI 2.2.1 as well as jRuby 1.7.21 and Rubinius 2.5.8 ... The difference between server1.rb and server2.rb is the use of the DisplayMessage and message class method in the latter.

server1.rb中使用sleep时,实际上使用的是Celluloid.sleep,但是在server2.rb中使用时,它使用的是Kernel.sleep ...,这会将邮箱锁定Server直到60秒已经通过.这样可以防止在邮箱再次处理消息(actor上的方法调用)之前,对该actor上的将来方法调用进行处理.

When sleep is used in server1.rb it is using Celluloid.sleep in actuality, but when used in server2.rb it is using Kernel.sleep ... which locks up the mailbox for Server until 60 seconds have passed. This prevents future method calls on that actor to be processed until the mailbox is processing messages ( method calls on the actor ) again.

显式调用 Celluloid.sleep 而不是sleep(如果未显式调用为Celluloid.sleep,则使用sleep会最终调用Kernel.sleep,因为DisplayMessage不会像Server那样include Celluloid)

Explicitly invoke Celluloid.sleep rather than sleep ( if not explicitly invoked as Celluloid.sleep, using sleep will end up calling Kernel.sleep since DisplayMessage does not include Celluloid like Server does )

server1.rb一样将DisplayMessage.message的内容带入handle_message;或至少进入Server(在Celluloid范围内),并将使用正确的 sleep .

Bring the contents of DisplayMessage.message into handle_message as in server1.rb; or at least into Server, which is in Celluloid scope, and will use the correct sleep.

def handle_message(message)
  defer {
    DisplayMessage.message(message)
  }
end

Celluloid.sleep方法:

The Celluloid.sleep approach:

class DisplayMessage
    def self.message(message)
      #de ...
      Celluloid.sleep 60
    end
end


并不是真正的范围问题;这是关于异步的.

重申一下,更深层的问题不是sleep的范围...这就是为什么deferfuture是我的最佳建议的原因.但是要在我的评论中发表一些意见:


Not truly a scope issue; it's about asynchrony.

To reiterate, the deeper issue is not the scope of sleep ... that's why defer and future are my best recommendation. But to post something here that came out in my comments:

使用deferfuture会推动一项任务,该任务会使actor陷入另一个线程.如果使用future,则可以在任务完成后获取返回值;如果使用defer,则可以触发&忘了.

Using defer or future pushes a task that would cause an actor to become tied up into another thread. If you use future, you can get the return value once the task is done, if you use defer you can fire & forget.

但是更好的是,为容易被束缚的任务创建另一个actor,甚至合并其他actor ...如果deferfuture对您不起作用.

But better yet, create another actor for tasks that tend to get tied up, and even pool that other actor... if defer or future don't work for you.

我很乐意回答这个问题带来的后续问题;我们有一个非常有效的邮件列表和IRC频道.您的慷慨解囊值得称赞,但我们中的许多人会纯粹为您提供帮助.

I'd be more than happy to answer follow-up questions brought up by this question; we have a very active mailing list, and IRC channel. Your generous bounties are commendable, but plenty of us would help purely to help you.

这篇关于了解赛璐oid并发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 19:19