1

我有一个控制器,它接收消息并将数据发布到第 3 方 url:

def create
    @message = Message.new(params[:message])

    if @message.valid?
      post_to_server(@message)
    end
end


private 

def post_to_server
 # Http Post to 3rd Party Url
end

Message 不是 ActiveRecord 对象。它是一个带有一些 ActiveModel 验证的普通 ruby​​ 对象。

现在我担心的是,如果我的应用程序正在等待来自 3rd 方服务器的响应,它可能会显得很慢。推迟执行此方法以便用户可以立即获得响应并且 post_to_server 部分在后台运行的最佳方法是什么?

我用谷歌搜索了一下,发现了这个:https ://github.com/collectiveidea/delayed_job

但这要求我的对象是一个活动的记录对象并保持不变。对于我需要的东西,这似乎有点矫枉过正。

有没有其他方法可以将方法的执行推迟到返回响应之后?

谢谢

4

2 回答 2

3

只有一种简单的方法可以做到这一点,那就是使用延迟作业或 resque 或任何其他提供延迟后台处理的 gem。发送请求是 IO 阻塞,所以如果你在延迟线程的情况下发送这个请求,你会阻塞 ruby​​ mri 中的当前进程。

DelayedJob 将使用 YAML 编组您的对象,然后将其转换回执行,因此您可以传递任何对象。

class Message
  def post_to_server
    # long running method
  end
  handle_asynchronously :post_to_server
end

@message.post_to_server 或者

class Jobs
  def self.post_to_server(message)
    # long running method
  end
  handle_asynchronously :post_to_server
end

Jobs.post_to_server(@message)

https://github.com/collectiveidea/delayed_job

于 2012-05-24T11:09:38.803 回答
2

我认为delayed_job 不太关心ActiveRecord 对象或持久性。如文档中所述:

在任何对象上调用 .delay.method(params) ,它将在后台处理。

https://github.com/collectiveidea/delayed_job#queuing-jobs

我们在我们的项目中使用它,效果很好。根据我的研究,delayed_job 是实现您所追求的最简单的方法。还有其他排队机制(RabbitMQ、ZeroMQ)也会有所帮助,但在我看来,这些都将是矫枉过正。

在您的情况下,请尝试以下操作:

@message.delay.post_to_server
于 2012-05-24T11:09:30.160 回答