【问题标题】:Using Rmagick with eventmachine将 Rmagick 与 eventmachine 一起使用
【发布时间】:2013-12-06 10:56:58
【问题描述】:

我正在尝试使用 Goliath 和 Grape 创建一个非常简单的 Web 服务。我的服务所做的只是给定图像路径和目标尺寸,它将返回图像的新几何形状。图像存储在与 Web 服务主机相同的服务器中。

所以我在 Grape 中有这段代码:

# some Grape code omitted
get "/" do
  EM.defer {
    image = Magick::Image.read('path to image').first
    image.change_geometry('3000x3900') do |cols, row, img|
      return {width: cols, height: row}
    end
  }
end

当我在浏览器中访问端点时,我得到的只是这个字符串

"#<ConditionVariable:0x007ffd9de1f6e8>"

如果没有 EM.defer,它会返回以下 json,但请求/秒非常低(大约 4 个请求/秒):

{width: 'new width', height: 'new heigth'}

如何使 Rmagick 操作非阻塞并返回结果?

【问题讨论】:

标签: ruby rmagick eventmachine grape goliath


【解决方案1】:

看起来你有点搞混了。

调用RMagick总是阻塞,因为它需要处理图像。好消息是对grape 的调用本身是非阻塞。这意味着,虽然您的单个客户端必须等待声称的 1/3 秒才能完成,但 另一个 客户端仍然能够对请求进行排队。

我猜你的测试环境只是一一调用相应的服务,等待请求完成。取而代之的是,您要从单独的线程调用服务,并在它们准备好时获取结果。

希望对你有帮助。

【讨论】:

  • 我知道 Rmagick 会阻止我的应用程序,因此我尝试将 EM.defer 与它一起使用。也许我的 EM.defer 实现有问题?
  • 我建议你在Grape 后面加上Sinatra,对吧?不需要重新实现Sinatra功能,请参考threaded选项here。无论如何,在 get 块内实现 EM#defer 是错误的,因为客户端在此处等待响应,您无法阻止从已阻塞的方法中阻塞。
  • 但是,你可以不阻塞所有其他请求的反应器线程,这就是 OP 使用 EM.defer 的原因
猜你喜欢
  • 2012-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多