【问题标题】:Delayed_job Won't Run User defined methodDelayed_job 不会运行用户定义的方法
【发布时间】:2012-03-30 12:39:12
【问题描述】:

我一直试图让 DelayedJob 在后台运行一些用户定义的方法。对于这个测试用例,我在帮助程序中定义了以下方法:

 def test_case
    u = User.new
     u.first_name = "JimBob"
     u.last_name = "joe"
     u.email = "itworked@eureka.com"
     u.password = "sailsJ123"
     u.password_confirmation = "sailsJ123"
     u.save
  end

然后,在控制器动作中,我定义:

  def action_name
     #whatever it does outside of this
     test_case

  end

这会导致 test_case 在此处的操作运行时创建一个新用户。如果我试图推迟工作,我将其更改为:

  def action_name
     #whatever it does outside of this
     self.delay.test_case
  end

这会导致创建延迟作业,但有某些迹象表明我做错了:具体来说,延迟作业表中的处理程序包含在 action_name 其他地方加载的所有信息(在本例中是一个非常大的文件,大约 50000个字符),而不仅仅是一个指定运行 test_case 之类的简单处理程序。

如果我改变这个来继续测试,我已经尝试过:

 def action_name
     #whatever it does outside of this
     u = User.new
     u.first_name = "JimBob"
     u.last_name = "joe"
     u.email = "itworked@eureka.com"
     u.password = "sailsJ123"
     u.password_confirmation = "sailsJ123"
     u.delay.save
  end

这成功创建了一个 DJ,并且正如预期的那样,它加载了一个指定细节的处理程序(例如 u.name => "JimBob"...)。但是当作业运行时,不会创建新用户。我什至尝试切换它只是为了销毁一个用户(尽管考虑到密码字段的处理方式,我可能用 DJ 创建一个用户可能很困难)但这不起作用。

长话短说:

  1. 如何让 DJ 正确运行后台方法?
  2. 在创建看似简单的延迟作业的情况下,如何不对数据库进行任何更改?

【问题讨论】:

  • DJ 处理程序对象和方法名称是什么?
  • @AMIT 它只是“Delayed Job”的缩写。

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


【解决方案1】:

这并不表示有问题:

delayed_job 表包含在 action_name 中其他地方加载的所有信息

在这种情况下这是可以预料的,因为您是这样说的:

self.delay.test_case

self 是控制器,它恰好有params 以及你可能不关心的各种其他东西; DJ 必须序列化self 以便为test_case 运行提供适当的上下文。也许你在某个地方遇到了大小限制,那个大文件卡在self 中。

我认为您的第二个“致电delay 处理其他事情”的方法正朝着正确的方向发展。

您可以尝试查询职位类别:

class ItsAJob
    def perform
        u = User.new
        u.first_name = "JimBob"
        u.last_name = "joe"
        u.email = "itworked@eureka.com"
        u.password = "sailsJ123"
        u.password_confirmation = "sailsJ123"
        u.save
    end
end

# and elsewhere...
Delayed::Job.enqueue(ItsAJob.new)

或者尝试让你的方法成为一个类方法,这样你就可以在一个类上.delay

class YourController
    def action_name
        self.class.delay.test_case
    end

    def self.test_case
        u = User.new
        u.first_name = "JimBob"
        u.last_name = "joe"
        u.email = "itworked@eureka.com"
        u.password = "sailsJ123"
        u.password_confirmation = "sailsJ123"
        u.save
    end

结束

【讨论】:

    【解决方案2】:

    您不能在 ActiveRecord 模型上延迟 #save,因为 DJ 会在执行您的操作之前尝试从数据库中重新加载模型。所有数据都将丢失。相反,使用创建用户的#perform 方法创建一个 Job 类。

    【讨论】:

    • 当您在 ActiveRecord 对象上延迟一个方法时,DJ 只是将方法、类名和 id 写入队列。当作业运行时,实际对象通过 id 从数据库中加载。由于它是新加载的,因此对象上未保存到数据库的任何状态都会丢失。以这种方式延迟对模型的更新将是无效的。
    猜你喜欢
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 2011-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多