如何与Rails 4同时处理请求?

时间:2014-02-06 14:14:32

标签: ruby-on-rails ruby concurrency puma

我正在尝试在Rails 4中同时提供多个请求,这是我在Rails 3中使用config.threadsafe!Puma轻松完成的。

说我有这个控制器

class ConcurrentController < ApplicationController
  def index
    sleep 10000
  end

  def show
  end
end

我曾经能够用puma -t 2:16 -p 3000(最少2个线程)启动puma并点击index然后show并仍然show正确渲染。< / p>

在Rails 4中,如果我尝试做同样的事情,Puma现在会锁定index请求并且show永远不会被渲染。当我为服务器点击Ctrl-C时,Puma给了我这个错误:

Rack app error: #<ThreadError: Attempt to unlock a mutex which is locked by another thread>

我在这里想要使用Rails 4获得并发性是什么?应该不需要config.threadsafe!(即使我尝试也没有区别)

3 个答案:

答案 0 :(得分:36)

我邀请您阅读本文Removing config.threadsafe!config.threadsafe!的配置选项 它将帮助您更好地理解config.threadsafe!的选项,特别是允许并发。

在Rails 4中默认设置为config.threadsafe!

现在回答

在Rails中,默认情况下,DEV环境中的Rack :: Lock中间件将4个请求包含在Mutex中。

如果您想启用并发,可以设置 config.allow_concurrency=true 。这将禁用Rack :: Lock中间件。我不会删除你在问题的另一个答案中提到的;这看起来像是对我的黑客攻击。

  

注意:如果您有config.cache_classes=true,则config.allow_concurrency(Rack :: Lock请求互斥锁)的分配不会被取消   效果,默认允许并发请求。如果你有   config.cache_classes=false,然后你可以设置   config.allow_concurrency truefalse config.cache_classes=false config.allow_concurrency=true 。在DEV中   环境你想要像这样

{{1}}
     

声明:这意味着如果config.cache_classes = false   (默认情况下,它在dev env中)我们不能并发   请求。不正确。

附录

你可以参考this answer,它建立了一个使用MRI和JRuby测试并发性的实验。结果令人惊讶。 MRI比JRuby快。

MRI并发性的实验是on GitHub。 该实验仅测试并发请求。控制器中没有竞争条件。但是,我认为从上面的文章中实现示例并不太难以测试控制器中的竞争条件。

答案 1 :(得分:21)

默认情况下,在Rails 4中,似乎未在开发环境中启用并发请求。

我在documentation中找到了这句话。

  

Rack :: Lock将应用程序包装在互斥锁中,因此一次只能由一个线程调用。仅在config.cache_classes为false时启用。

这意味着如果config.cache_classes = false(默认情况下在dev env中),我们就不能有并发请求。

并发请求可以在生产环境中使用我的示例。

一种解决方案是在开发环境中设置config.cache_classes = true,但是代码不会在更改时重新加载,这对于开发来说并不真正有效。

第二种hacky解决方案是禁用开发中的Rack::Lock中间件。

因此,如果您要在development.rb中添加以下行:

config.middleware.delete Rack::Lock

您应该能够在开发环境中禁用缓存类来同时发出请求。

答案 2 :(得分:-1)

你可以尝试独角兽,这在开发模式下非常简单:

http://dave.is/unicorn.html