2

我在之前的代码中使用 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 扩展,如 resque-status 使用 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 的参数,但不能找到延迟。那么我该如何处理延迟的工作呢?

谢谢!

4

2 回答 2

0

resque-schedulerscheduled每当它为您的工作人员创建工作时,将调用提供的类上的方法。它还可以很好地将队列名称和类名称作为字符串传递,因此您可以创建一个类级别的方法来处理计划的作业创建。

虽然法比奥的回答将解决问题,但回答您的具体问题有点过度设计。假设您有一个JobWithStatus所有resque-status工作人员都继承自的类,您只需向其添加scheduled方法即可使其与resque-scheduleras 一起使用:

class JobWithStatus
  include Resque::Plugins::Status

  def self.scheduled(queue, klass, *args)
    Resque.constantize(klass).create(*args)
  end
end
于 2015-01-15T02:17:53.300 回答
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文件夹中。在后一种情况下,请记住在某处要求它。

于 2013-09-17T13:17:07.670 回答