【问题标题】:Defer execution of a method in rails 3延迟在rails 3中执行方法
【发布时间】:2012-05-24 19:26:51
【问题描述】:

我有一个控制器,它接收消息并将数据发布到第 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

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

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

谢谢

【问题讨论】:

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


    【解决方案1】:

    只有一种简单的方法可以做到这一点,那就是使用延迟作业或 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

    【讨论】:

    • 我尝试了 self.delay.post_to_server 并得到一个错误:无法转储匿名模块:#<0x175eb28c>
    【解决方案2】:

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

    在任何对象上调用 .delay.method(params) 都会在后台处理。

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

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

    在你的情况下尝试类似:

    @message.delay.post_to_server
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-03
      • 1970-01-01
      相关资源
      最近更新 更多