【问题标题】:Render status 200 before executing code in rails controller在 Rails 控制器中执行代码之前渲染状态 200
【发布时间】:2014-04-14 17:53:34
【问题描述】:

我正在集成一个通信 api,每当文本/语音到达我的服务器(rails 控制器)时,我必须向 api 发回 OK (200)。我想在执行我的代码块之前发送此响应,因为如果我的代码中断(并且无法发送 OK),通信 api 会持续发送消息长达 3 天。现在这只会使我的服务器上已经存在的问题复杂化,因为它会随着相同的消息不断出现而不断中断。

我做了一些研究,找到了两个解决方案。

解决方案 1: 第一个解决方案如下(我当前的实现),但它似乎不起作用(除非我没有正确读取日志文件或产生幻觉)。

def receive_text_message
   head :ok, :content_type => 'text/html'   
   # A bunch of code down here
end

我认为应该这样做(根据 rails doc),但我不确定是否可以。

解决方案 2: 我正在考虑的第二个实现是快速创建一个新进程/线程来执行代码块并终止接收消息的进程......这样api 很快就可以了,它不必等待我的代码块成功执行。我可以用产卵(或产卵)宝石来做到这一点。因为我使用乘客(社区)服务器,所以我会创建一个流程。但是新进程会占用更多内存,而且我认为调试子进程/线程更难(我可能错了)

感谢您的帮助!

附带问题:rails 是否会在刚刚失败后尝试重新启动进程?

【问题讨论】:

  • 这可能会让你感兴趣edgar.tumblr.com/post/9880562940/…
  • 我同意解决方案 #2。您可以使用 Resque 或 Sidekiq 之类的工具,并将作业排队等待在自己的时间内完成。
  • Yoshiji 先生我去看看。 @Kurt Funai 我宁愿不使用 Resque 和 co。但我认为 Sidekiq 是 Spawning gem 的干净替代品。但是为了确定,一旦我在上面的控制器中调用了sidekiq的perform_async方法,这个控制器会结束并返回吗?
  • 我个人只对 Resque 有经验,但是是的,在对作业进行排队后,控制器将继续执行。在继续之前,它不会等待实用程序服务器处理该作业。 perform_async 之后你拥有的任何东西都会被执行(比如你的 return)。

标签: ruby-on-rails ruby model-view-controller ruby-on-rails-4


【解决方案1】:

您可以选择在控制器中返回 200 并启动 sidekiq 作业。这样 200 将立即返回,您的控制器将准备好处理下一个作业。因此,不会在控制器中浪费时间和资源。让工人做真正艰苦的工作。

在你的控制器中

def receive_text_message
   head :ok, :content_type => 'text/html'   
   HardWorker.perform_async(params)
end

在您的 sidekiq 工作人员中:

class HardWorker
  include Sidekiq::Worker

  def perform(params)
    # 'Doing hard work'
  end
end

我喜欢 sidekiq 主要是因为它比救援更好地处理资源。

【讨论】:

  • @Boti...lol 我想我喜欢这个选项。这是两种解决方案的混合体。我将在本周晚些时候尝试一下。出于好奇......所以没有sidekiq,你是说我的控制器在代码块完全执行之前无法处理新请求?
猜你喜欢
  • 2014-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-21
  • 1970-01-01
  • 1970-01-01
  • 2022-08-03
  • 1970-01-01
相关资源
最近更新 更多