1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

DelayedJobのhandlerをRubyオブジェクトに変換する

Last updated at Posted at 2021-07-05

背景

DelayedJobを利用して定期実行しているタスクがあるのですが、処理時間が長いと全く同じタスクが並列して走ってしまうことがありました。
(cronを利用しないのはサーバーのリソースが枯れてしまわないように数を制限しているため)

既に実行されている(locked_atに時間が入っているもの)のhandlerから何のタスクが実行されているか分かれば後からキューイングされたジョブの実行をスキップする処理ができるなと思い調べたのですが変換方法が調べても出てこなかったので記事にしました。

handlerの取り出し

まずは結論から書きたいと思います。

handler = Delayed::Job.first
YAML.load_dj(handler)

上記のようにYAML#load_djを利用することでDelayed::Jobを使ってenqueueしたジョブのhandlerをRubyのオブジェクトに変換することができます。
できたオブジェクトはenqueuしたときのクラスなので、例のようにクラス変数のnameなどを取り出したい場合は元のクラスで参照できるようにattr_readerなどの設定をする必要があります。

class.rb
class A
  attr_reader :name
  def initialize
    @id = 'id'
    @name = 'name'
  end

  def enqueue
    Delayed::Job.enqueue~~~
  end
end

A.new.enqueue
handler = Delayed::Job.first
task = YAML.load_dj(handler)
=> #<A ~~~~~>
task.name
=> name

load_djの実装

ちなみにこの取り出し方はDelayed::Jobでワーカーが取り出す際に利用しているものでこちらから確認できます。

delayed_job/base.rb
def payload_object
  @payload_object ||= YAML.load_dj(handler)
rescue TypeError, LoadError, NameError, ArgumentError, SyntaxError, Psych::SyntaxError => e
  raise DeserializationError, "Job failed to load: #{e.message}. Handler: #{handler.inspect}"
end

また、YAMLモジュールをオーバライドしている箇所はこちらになります

delayed_job/psych_ext.rb
module Psych
  def self.load_dj(yaml)
    result = parse(yaml)
    result ? Delayed::PsychExt::ToRuby.create.accept(result) : result
  end
end

最後に

もう少し実装を抽象化できればDelayed::Jobに実装しても良い機能なきもするので実装を考えてみたいと思います。
本記事が誰かの役に立てれ立てれば嬉しいです

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?