我在之前的代码中使用resque-scheduler进行延迟作业:
Resque.enqueue_in(options[:delay].seconds, self, context)
现在我想要包含resque-status来完成这项工作,但不知道它们如何协同工作。最新的resque-status源代码支持调度程序,如源代码所示:
https://github.com/quirkey/resque-status/blob/master/lib/resque/plugins/status.rb
# Wrapper API to forward a Resque::Job creation API call into a Resque::Plugins::Status call.
# This is needed to be used with resque scheduler
# http://github.com/bvandenbos/resque-scheduler
def scheduled(queue, klass, *args)
self.enqueue_to(queue, self, *args)
end
端
但我不确定如何使用它。我应该调用SampleJob.scheduled(queue,myclass,:delay => delay)而不是SampleJob.create(options)吗?
=============================================== =======================
此外,还支持resque-status(以及其他自定义作业):
https://github.com/bvandenbos/resque-scheduler
某些像resque-status这样的Resque扩展使用具有略微不同的API签名的自定义作业类。 Resque-scheduler不会尝试支持所有现有和未来的自定义作业类,而是支持计划标记,因此您可以扩展自定义类并使其支持计划作业。
让我们假装我们有一个名为FakeLeaderboard的JobWithStatus类
class FakeLeaderboard < Resque::JobWithStatus
def perform
# do something and keep track of the status
end
end
然后是时间表:
create_fake_leaderboards:
cron: "30 6 * * 1"
queue: scoring
custom_job_class: FakeLeaderboard
args:
rails_env: demo
description: "This job will auto-create leaderboards for our online demo and the status will update as the worker makes progress"
但似乎只适用于经常性工作。我可以找到cron的参数,但不能延迟。那么如何处理延迟的工作?
谢谢!
答案 0 :(得分:0)
我遇到了同样的问题,我通过实施一个为“统计”工作提供跑步者的模块自行解决。
module Resque # :nodoc:
# Module to include in your worker class to get resque-status
# and resque-scheduler integration
module ScheduledJobWithStatus
extend ActiveSupport::Concern
included do
# Include status functionalities
include Resque::Plugins::Status
end
# :nodoc:
module ClassMethods
# This method will use a custom worker class to enqueue jobs
# with resque-scheduler plugin with status support
def enqueue_at(timestamp, *args)
class_name = self.to_s # store class name since plain class object are not "serializable"
Resque.enqueue_at(timestamp, JobWithStatusRunner, class_name, *args)
end
# Identical to enqueue_at but takes number_of_seconds_from_now
# instead of a timestamp.
def enqueue_in(number_of_seconds_from_now, *args)
enqueue_at(Time.now + number_of_seconds_from_now, *args)
end
end
end
# Wrapper worker for enqueuing
class JobWithStatusRunner
# default queue for scheduling jobs with status
@queue = :delayed
# Receive jobs from {Resque::ScheduledJobWithStatus} queue them in Resque
# with support for status informations
def self.perform(status_klass, *args)
# Retrieve original worker class
klass = status_klass.to_s.constantize
# Check if supports status jobs
unless klass.included_modules.include? Resque::Plugins::Status
Rails.logger.warn("Class #{klass} doesn't support jobs with status")
return false
end
Rails.logger.debug("Enqueing jobs #{klass} with arguments #{args}")
klass.create(*args)
rescue NameError
Rails.logger.error("Unable to enqueue jobs for class #{status_klass} with args #{args}")
false
end
end
end
通过这种方式,您可以使用以下简单语法将作业排入队列:
# simple worker class
class SleepJob
# This provides integrations with both resque-status and resque-scheduler
include Resque::ScheduledJobWithStatus
# Method triggered by resque
def perform
total = (options['length'] || 60).to_i
1.upto(total) { |i| at(i, total, "At #{i} of #{total}"); sleep(1) }
end
end
# run the job delayed
SleepJob.enqueue_in(5.minutes)
# or
SleepJob.enqueue_at(5.minutes.from_now)
只需将模块放入resque初始化程序或lib
文件夹中即可。在后一种情况下,请记住在某处需要它。
答案 1 :(得分:0)
resque-scheduler
只要为您的工作人员创建作业消耗,就会在提供的类上调用scheduled
方法。
它还很好地将队列名称和类名称作为字符串传递,因此您可以创建一个类级别方法来处理预定的作业创建。
虽然Fabio的答案将解决问题,但回答您的具体问题有点过于设计。
假设您拥有JobWithStatus
所有resque-status
工作人员继承的课程,则只需添加scheduled
方法即可使其与resque-scheduler
一起使用,如下所示:
class JobWithStatus
include Resque::Plugins::Status
def self.scheduled(queue, klass, *args)
Resque.constantize(klass).create(*args)
end
end