にconfig/application.rb
、以下を追加します
config.autoload_paths += Dir["#{config.root}/app/jobs/**/"]
に新しいディレクトリを作成しますapp/jobs/
。
app/jobs/api_job.rb
次のようなファイルを作成します
class ApiJob < Struct.new(:attr1, :attr2, :attr3)
attr_accessor :token
def initialize(*attrs)
self.token = self.class.token(attr1, attr2, attr3)
end
def display_name
self.class.token(attr1, attr2, attr3)
end
#
# Class methods
#
def self.token(attr1, attr2, attr3)
[name.parameterize, attr1.id, attr2.id, attr3.id].join("/")
end
def self.find_by_token(token)
Delayed::Job.where("handler like ?", "%token: #{token}%")
end
end
注: 、、およびを、キューに入れられたタスクを実行するために渡すために必要な数の属性(存在する場合)にattr1
置き換えます。これをすぐに呼び出す方法の詳細attr2
attr3
ApiJob
いくつかのget_and_create_or_update_users
メソッドをキューに入れるAPIごとに、別のメソッドを作成しますJob
。たとえば、Facebook
APIモデルがある場合app/jobs/facebook_api_job.rb
、次のようなクラスがある可能性があります。
class FacebookApiJob < ApiJob
def perform
FacebookApi.new.get_and_create_or_update_users(attr1, attr2, attr3)
end
end
注:質問では、に属性を渡していませんget_and_create_or_update_users
。属性を渡す必要がある場合に、これをどこで行うかを示しています。
最後に、あなたrefresh_users_list
が定義されているところならどこでも、このjob_exists?
メソッドのようなものを定義してください
def job_exists?(tokens)
tokens = [tokens] if !tokens.is_a?(Array) # allows a String or Array of tokens to be passed
tokens.each do |token|
return true unless ApiJob.find_by_token(token).empty?
end
false
end
これで、andループ内で、refresh_users_list
新しいトークンを作成し、呼び出しjob_exists?
てAPIのジョブがキューに入れられているかどうかを確認できます。例えば
# Build a token
def refresh_users_list
apis_array.each do |api|
token = ApiJob.token(attr1, attr2, attr3)
next if job_exists?(token)
api.myclass.new.delay.get_and_create_or_update_users
end
end
注:ここでも指摘したいのですが、上記のコードをドロップして機能させることはできません。アプリケーションと実行しているジョブに合わせて調整する必要があります。
なぜこれほど複雑なのですか?
私の調査によると、提供されるものを通じてキューに入れられたジョブに「タグ付け」または一意に識別する方法はありませんdelayed_job
。もちろん、各ジョブには固有の:id
属性があります。作成された各ジョブのID値をどこかのハッシュに保存できます
{
"FacebookApi": [1, 4, 12],
"TwitterApi": [3, 193, 44],
# ...
}
次に、対応するハッシュキーでIDを確認しますが、この制限があり、問題に対して必ずしも十分ではありません。上記のように複数の属性で特定のジョブを識別する必要がある場合は、これらのジョブを見つける方法を作成する必要があります(メモリにジョブし、それらをループして、基準に一致するかどうかを確認します)。
これはどのように機能していますか?
extendsにはStruct
属性があります。このトークンは、渡された属性(、、)に基づいており、拡張する新しいクラスがインスタンス化されたときに作成されます。ApiJob
:token
attr1
attr2
attr3
ApiJob
クラスメソッドは、同じクラスメソッドを使用して作成されたトークンに基づいてfind_by_token
、キュー内のジョブの文字列表現で一致するものを検索するだけです。delayed_job
token