Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/53.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails EventMachine和Ruby线程-什么';这到底是怎么回事?_Ruby On Rails_Ruby_Eventmachine - Fatal编程技术网

Ruby on rails EventMachine和Ruby线程-什么';这到底是怎么回事?

Ruby on rails EventMachine和Ruby线程-什么';这到底是怎么回事?,ruby-on-rails,ruby,eventmachine,Ruby On Rails,Ruby,Eventmachine,我们一起使用Rails和EventMachine,当对乘客使用该组合时,需要进行一些非常具体的设置。经过大量的尝试和错误,我让EventMachine初始化工作得很好,但我想更好地理解代码。正如您在下面的代码片段中所看到的,我们的初始值设定项检查乘客,然后在重新启动EventMachine之前检查它是否是分叉进程 if defined?(PhusionPassenger) PhusionPassenger.on_event(:starting_worker_process) do |fork

我们一起使用Rails和EventMachine,当对乘客使用该组合时,需要进行一些非常具体的设置。经过大量的尝试和错误,我让EventMachine初始化工作得很好,但我想更好地理解代码。正如您在下面的代码片段中所看到的,我们的初始值设定项检查乘客,然后在重新启动EventMachine之前检查它是否是分叉进程

if defined?(PhusionPassenger)
  PhusionPassenger.on_event(:starting_worker_process) do |forked|
  # for passenger, we need to avoid orphaned threads
    if forked && EM.reactor_running?
      EM.stop
    end
    Thread.new {
      EM.run do
我的问题与EM.U运行有关?和EM.stop命令。如果Passenger已经分叉了我们的进程,为什么我需要在新线程中重新启动EM引用?如果EM.U正在运行?返回true,我引用的EM实例是什么


您可以在我们的博客上看到完整的初始化器代码。首先,每个Ruby进程只有一个EventMachine实例,因此无论发生什么,您都会引用同一个EM实例,而不依赖于您当前所在的线程

您可以在一个新的、单独的线程中运行reactor,这样它就不会阻塞主线程(其目的是服务于web请求)。否则EM.run将接管控制,进入其运行循环,不再离开EM.run块。你在运行吗?如果EM循环正在某处运行,则返回true。由于每个Ruby进程只有一个,因此该方法很容易判断EM是否正在运行

这里的设置是在正常Ruby进程中使用EM的最简单方法,不会干扰正在运行的其他任何东西。我假设您正在从web应用程序将消息推送到AMQP代理。每当您发送一条消息时,它都会进入单独线程中EM的运行循环,这一部分对您来说非常透明,并且不会影响主循环,主循环可以继续处理Rails web请求。但是要小心,总是使用EM将东西推到EM循环上。尝试在不同线程中处理EM打开的套接字可能会导致糟糕的事情发生,我在生产中看到过,顺便说一句,使用并构建一个名为oching;)的库


在启动新的EM循环之前停止EM循环会处理父进程遗留下来的EM循环,这可能会导致在父进程中使用EM打开文件描述符时出现问题。在自定义代码中,使用EM.fork_reactor可以避免这种情况,但由于父进程不受您的控制,因此最安全的做法是在启动新实例之前检查反应器是否存在并停止它。

非常好的描述,谢谢。我很清楚需要在它自己的线程中运行EM,但是当你说“EM循环可能会被遗留下来”时,这就是我有点不清楚的地方。EM循环如何得到“剩余”?我不会关闭它们的父进程,对吗?这正是你要做的。您正在关闭父进程中可能剩余的EM。如果EM循环在父进程中运行,它也会被分叉,但您通常对父进程中遗留的文件描述符一点也不感兴趣,因此您可以从头开始。考虑到Passenger不太可能单独运行EM循环,这更像是一种安全措施。类似地,我正在通过ruby amqp gem与RabbitMQ合作,在一个运行在thin下的websocket应用程序中。Thin有自己的EventMachine循环,我目前正在使用EventMachine。下一步请点击进入并完成我的amqp工作。这是正确的还是我应该使用EventMachine.fork_reactor给AMQP它自己的EM使用?@wchrisjohnson您应该可以使用Thin创建的reactor
fork_reactor
创建了一个新的进程,该进程不再具有瘦web服务器的上下文,我假设您需要集成WebSockets。谢谢-正是这种情况。