Delayed_job (2.1.4) 错误:作业加载失败:需要 IO 实例。处理程序无

发布于 2024-12-13 08:08:01 字数 1658 浏览 2 评论 0原文

我创建了一个简单的成就系统,并想引入delayed_job(2.1.4)来处理处理。但是,delayed_jobs 表中的 handler 列始终为 nil,这会导致 last_error 文本: Job failed to load: instance of IO required。 Handler nil

这是我的设置:

Achievement Observer

class AchievementObserver < ActiveRecord::Observer
  observe User, Comment, ...

  def after_create(record)
    # initiate delayed job to check conditions
    Delayed::Job.enqueue(TrophyJob.new(record.id, record.class.name))
  end
  ...
end

Trophy Job 系统

class TrophyJob < Struct.new(:record_id, :record_type)
  def perform
    case record_type
    when "User"
      UserProfileCompleteTrophy.progress(User.find(record_id)) # complete your profile settings
      NewsletterReceiverTrophy.progress(User.find(record_id)) # sign up for the newsletter
    when "Comment"
      CommentsAuthoredTrophy.progress(Comment.find(record_id)) # create x comments
    ...
    end
  end
end

会创建delayed_jobs 表中的条目。但是,处理程序始终为 NULL。我已经尝试过各种事情(之前通过完整的对象,现在选择 id + 类名,如下所述: delayed_job 出现奇怪的异常;在观察者中尝试了 xxxTrophy.delay.progress(...) ;等等) - 都没有运气。

也有

require 'yaml'
YAML::ENGINE.yamler= 'syck'

我的 boot.rb 中

。值得一提的是:虽然 last_error 文本被delayed_job 填充,但是 attempts 和 failed_at 列仍然为 NULL。

我缺少什么?

更新

我验证了序列化是否按预期工作:

ruby-1.9.2-p290 :004 > TrophyJob.new(1, "User").to_yaml
 => "--- !ruby/struct:TrophyJob \nrecord_id: 1\nrecord_type: User\n"

I created a simplistic achievements system and wanted to introduce delayed_job (2.1.4) to take care of the processing. However, the handler column in the delayed_jobs table is always nil, which results in the last_error text: Job failed to load: instance of IO needed. Handler nil

Here is my setup:

Achievement Observer

class AchievementObserver < ActiveRecord::Observer
  observe User, Comment, ...

  def after_create(record)
    # initiate delayed job to check conditions
    Delayed::Job.enqueue(TrophyJob.new(record.id, record.class.name))
  end
  ...
end

Trophy Job

class TrophyJob < Struct.new(:record_id, :record_type)
  def perform
    case record_type
    when "User"
      UserProfileCompleteTrophy.progress(User.find(record_id)) # complete your profile settings
      NewsletterReceiverTrophy.progress(User.find(record_id)) # sign up for the newsletter
    when "Comment"
      CommentsAuthoredTrophy.progress(Comment.find(record_id)) # create x comments
    ...
    end
  end
end

The entry in the delayed_jobs table gets created. However, the handler is always NULL. I've already tried various things (passed through complete objects before, now went for id + classname as described here: Weird exception with delayed_job; tried xxxTrophy.delay.progress(...) in the observer; etc.) - all without luck.

I also have

require 'yaml'
YAML::ENGINE.yamler= 'syck'

in my boot.rb.

One thing worth mentioning: Although the last_error text gets filled by delayed_job, the attempts and failed_at columns remain NULL.

What am I missing?

UPDATE

I verified that serialization works as one would expect:

ruby-1.9.2-p290 :004 > TrophyJob.new(1, "User").to_yaml
 => "--- !ruby/struct:TrophyJob \nrecord_id: 1\nrecord_type: User\n"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

身边 2024-12-20 08:08:01

找到解决方案:我的问题是由批量分配保护引起的。我有一个初始化程序来防止批量分配:

# SECURITY: protect against mass assignment vulnerabilities
# enforces explicitly setting attributes accessible in models (whitelisting)
ActiveRecord::Base.send(:attr_accessible, nil)

这阻止了elasto_job访问处理程序字段!不确定这是否可以被视为 DJ 中的错误。这是解决我的问题的初始化代码:

# Imortant: delayed job requires some attributes to be accessible - make sure they are
Delayed::Job.attr_accessible :priority, :payload_object, :handler, :run_at, :failed_at

Found the solution: my problem was caused by mass-assignment protection. I have an initializer to protect against mass-assignment:

# SECURITY: protect against mass assignment vulnerabilities
# enforces explicitly setting attributes accessible in models (whitelisting)
ActiveRecord::Base.send(:attr_accessible, nil)

This prevented delayed_job to access the handler field! Not sure if this can be considered a bug in DJ. Here is the initializer code that solved my problem:

# Imortant: delayed job requires some attributes to be accessible - make sure they are
Delayed::Job.attr_accessible :priority, :payload_object, :handler, :run_at, :failed_at
心清如水 2024-12-20 08:08:01

您的处理程序列可能对于放入其中的内容来说太小。您可以在迁移中修复此问题,如下所示:

change_column :delayed_jobs, :handler, :text, :limit => 64.kilobytes + 1

It's possible that your handler column is too small for what's being put into it. you can fix this in a migration like so:

change_column :delayed_jobs, :handler, :text, :limit => 64.kilobytes + 1
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文