推迟在rails 3中执行方法

时间:2012-05-24 10:58:14

标签: ruby-on-rails ruby ruby-on-rails-3 delayed-job

我有一个控制器,它接收一条消息并将数据发布到第三方网址:

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

消息不是ActiveRecord对象。它是一个普通的ruby对象,带有一些ActiveModel验证。

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

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

但是这需要我的对象是一个活动的记录对象并持久存在。对于我需要的东西来说,这似乎有点矫枉过正。

在返回响应之前,还有其他方法可以推迟执行方法吗?

由于

2 个答案:

答案 0 :(得分:3)

只有一种简单的方法可以使用delayedjob或resque或任何其他提供延迟后台处理的宝石。发送请求是IO阻塞,所以如果你发送这个请求,如果是deffered thread,你阻止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

答案 1 :(得分:2)

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

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

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

我们在项目中使用它并取得了良好的效果。根据我的研究,delayed_job是实现你所追求的最简单的方法。还有其他排队机制(RabbitMQ,ZeroMQ)也会有所帮助,但在我看来,这些机制将会有些过度。

在你的情况下尝试类似:

@message.delay.post_to_server