diff options
Diffstat (limited to 'activejob/lib')
-rw-r--r-- | activejob/lib/active_job/arguments.rb | 36 | ||||
-rw-r--r-- | activejob/lib/active_job/base.rb | 43 | ||||
-rw-r--r-- | activejob/lib/active_job/core.rb | 4 | ||||
-rw-r--r-- | activejob/lib/active_job/gem_version.rb | 2 | ||||
-rw-r--r-- | activejob/lib/active_job/logging.rb | 2 | ||||
-rw-r--r-- | activejob/lib/active_job/queue_adapter.rb | 7 | ||||
-rw-r--r-- | activejob/lib/active_job/queue_adapters.rb | 6 | ||||
-rw-r--r-- | activejob/lib/active_job/queue_adapters/inline_adapter.rb | 2 | ||||
-rw-r--r-- | activejob/lib/active_job/queue_adapters/qu_adapter.rb | 4 | ||||
-rw-r--r-- | activejob/lib/active_job/queue_adapters/queue_classic_adapter.rb | 10 | ||||
-rw-r--r-- | activejob/lib/active_job/queue_adapters/sidekiq_adapter.rb | 8 | ||||
-rw-r--r-- | activejob/lib/active_job/queue_name.rb | 11 | ||||
-rw-r--r-- | activejob/lib/active_job/test_helper.rb | 2 |
13 files changed, 109 insertions, 28 deletions
diff --git a/activejob/lib/active_job/arguments.rb b/activejob/lib/active_job/arguments.rb index 099ea4d169..e2c076eb3f 100644 --- a/activejob/lib/active_job/arguments.rb +++ b/activejob/lib/active_job/arguments.rb @@ -24,10 +24,16 @@ module ActiveJob extend self TYPE_WHITELIST = [ NilClass, Fixnum, Float, String, TrueClass, FalseClass, Bignum ] + # Serializes a set of arguments. Whitelisted types are returned + # as-is. Arrays/Hashes are serialized element by element. + # All other types are serialized using GlobalID. def serialize(arguments) arguments.map { |argument| serialize_argument(argument) } end + # Deserializes a set of arguments. Whitelisted types are returned + # as-is. Arrays/Hashes are deserialized element by element. + # All other types are deserialized using GlobalID. def deserialize(arguments) arguments.map { |argument| deserialize_argument(argument) } rescue => e @@ -35,12 +41,15 @@ module ActiveJob end private + GLOBALID_KEY = '_aj_globalid'.freeze + private_constant :GLOBALID_KEY + def serialize_argument(argument) case argument when *TYPE_WHITELIST argument when GlobalID::Identification - argument.to_global_id.to_s + { GLOBALID_KEY => argument.to_global_id.to_s } when Array argument.map { |arg| serialize_argument(arg) } when Hash @@ -61,16 +70,37 @@ module ActiveJob when Array argument.map { |arg| deserialize_argument(arg) } when Hash - argument.each_with_object({}.with_indifferent_access) do |(key, value), hash| - hash[key] = deserialize_argument(value) + if serialized_global_id?(argument) + deserialize_global_id argument + else + deserialize_hash argument end else raise ArgumentError, "Can only deserialize primitive arguments: #{argument.inspect}" end end + def serialized_global_id?(hash) + hash.size == 1 and hash.include?(GLOBALID_KEY) + end + + def deserialize_global_id(hash) + GlobalID::Locator.locate hash[GLOBALID_KEY] + end + + def deserialize_hash(serialized_hash) + serialized_hash.each_with_object({}.with_indifferent_access) do |(key, value), hash| + hash[key] = deserialize_argument(value) + end + end + + RESERVED_KEYS = [GLOBALID_KEY, GLOBALID_KEY.to_sym] + private_constant :RESERVED_KEYS + def serialize_hash_key(key) case key + when *RESERVED_KEYS + raise SerializationError.new("Can't serialize a Hash with reserved key #{key.inspect}") when String, Symbol key.to_s else diff --git a/activejob/lib/active_job/base.rb b/activejob/lib/active_job/base.rb index a3bec1f827..8f4b37222a 100644 --- a/activejob/lib/active_job/base.rb +++ b/activejob/lib/active_job/base.rb @@ -6,7 +6,48 @@ require 'active_job/execution' require 'active_job/callbacks' require 'active_job/logging' -module ActiveJob +module ActiveJob #:nodoc: + # = Active Job + # + # Active job objects can be configured to work with different backend + # queuing frameworks. To specify a queue adapter to use: + # + # ActiveJob::Base.queue_adapter = :inline + # + # A list of supported adapters can be found in QueueAdapters. + # + # Active job objects can be defined by creating a class that inherits + # from the ActiveJob::Base class. The only necessary method to + # implement is the "perform" method. + # + # To define an Active Job object: + # + # class ProcessPhotoJob < ActiveJob::Base + # def perform(photo) + # photo.watermark!('Rails') + # photo.rotate!(90.degrees) + # photo.resize_to_fit!(300, 300) + # photo.upload! + # end + # end + # + # Records that are passed in are serialized/deserialized using Global + # Id. More information can be found in Arguments. + # + # To queue a job to be processed asynchronously immediately: + # + # ProcessPhotoJob.perform_later(photo) + # + # To queue a job to be processed at some point in the future: + # + # ProcessPhotoJob.set(wait_until: Date.tomorrow.noon).perform_later(photo) + # + # More information can be found in ActiveJob::Core::ClassMethods#set + # + # == Exceptions + # + # * DeserializationError - Error class for deserialization errors. + # * SerializationError - Error class for serialization errors. class Base include Core include QueueAdapter diff --git a/activejob/lib/active_job/core.rb b/activejob/lib/active_job/core.rb index 9db23cc9da..f55db5a588 100644 --- a/activejob/lib/active_job/core.rb +++ b/activejob/lib/active_job/core.rb @@ -40,9 +40,9 @@ module ActiveJob # # VideoJob.set(queue: :some_queue).perform_later(Video.last) # VideoJob.set(wait: 5.minutes).perform_later(Video.last) - # VideoJob.set(wait_until: Time.tomorroe).perform_later(Video.last) + # VideoJob.set(wait_until: Time.now.tomorrow).perform_later(Video.last) # VideoJob.set(queue: :some_queue, wait: 5.minutes).perform_later(Video.last) - # VideoJob.set(queue: :some_queue, wait_until: Time.tomorroe).perform_later(Video.last) + # VideoJob.set(queue: :some_queue, wait_until: Time.now.tomorrow).perform_later(Video.last) def set(options={}) ConfiguredJob.new(self, options) end diff --git a/activejob/lib/active_job/gem_version.rb b/activejob/lib/active_job/gem_version.rb index 1f25d48326..f80e6563b8 100644 --- a/activejob/lib/active_job/gem_version.rb +++ b/activejob/lib/active_job/gem_version.rb @@ -8,7 +8,7 @@ module ActiveJob MAJOR = 4 MINOR = 2 TINY = 0 - PRE = "beta1" + PRE = "beta2" STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") end diff --git a/activejob/lib/active_job/logging.rb b/activejob/lib/active_job/logging.rb index bb96668cfb..6e703faaa7 100644 --- a/activejob/lib/active_job/logging.rb +++ b/activejob/lib/active_job/logging.rb @@ -3,7 +3,7 @@ require 'active_support/tagged_logging' require 'active_support/logger' module ActiveJob - module Logging + module Logging #:nodoc: extend ActiveSupport::Concern included do diff --git a/activejob/lib/active_job/queue_adapter.rb b/activejob/lib/active_job/queue_adapter.rb index fb54aec75e..4bd28522ab 100644 --- a/activejob/lib/active_job/queue_adapter.rb +++ b/activejob/lib/active_job/queue_adapter.rb @@ -2,12 +2,15 @@ require 'active_job/queue_adapters/inline_adapter' require 'active_support/core_ext/string/inflections' module ActiveJob - module QueueAdapter + module QueueAdapter #:nodoc: extend ActiveSupport::Concern module ClassMethods mattr_reader(:queue_adapter) { ActiveJob::QueueAdapters::InlineAdapter } + # Specify the backend queue provider. The default queue adapter + # is the :inline queue. See QueueAdapters for more + # information. def queue_adapter=(name_or_adapter) @@queue_adapter = \ case name_or_adapter @@ -26,4 +29,4 @@ module ActiveJob end end end -end
\ No newline at end of file +end diff --git a/activejob/lib/active_job/queue_adapters.rb b/activejob/lib/active_job/queue_adapters.rb index e865c901ce..efbcd3cb3a 100644 --- a/activejob/lib/active_job/queue_adapters.rb +++ b/activejob/lib/active_job/queue_adapters.rb @@ -7,7 +7,7 @@ module ActiveJob # * {Delayed Job}[https://github.com/collectiveidea/delayed_job] # * {Qu}[https://github.com/bkeepers/qu] # * {Que}[https://github.com/chanks/que] - # * {QueueClassic 2.x}[https://github.com/ryandotsmith/queue_classic/tree/v2.2.3] + # * {queue_classic}[https://github.com/QueueClassic/queue_classic] # * {Resque 1.x}[https://github.com/resque/resque/tree/1-x-stable] # * {Sidekiq}[http://sidekiq.org] # * {Sneakers}[https://github.com/jondot/sneakers] @@ -20,7 +20,7 @@ module ActiveJob # | Backburner | Yes | Yes | Yes | Yes | Job | Global | # | Delayed Job | Yes | Yes | Yes | Job | Global | Global | # | Que | Yes | Yes | Yes | Job | No | Job | - # | Queue Classic | Yes | Yes | No* | No | No | No | + # | queue_classic | Yes | Yes | No* | No | No | No | # | Resque | Yes | Yes | Yes (Gem) | Queue | Global | Yes | # | Sidekiq | Yes | Yes | Yes | Queue | No | Job | # | Sneakers | Yes | Yes | No | Queue | Queue | No | @@ -29,7 +29,7 @@ module ActiveJob # | Active Job | Yes | Yes | Yes | No | No | No | # # NOTE: - # Queue Classic does not support Job scheduling. However you can implement this + # queue_classic does not support Job scheduling. However you can implement this # yourself or you can use the queue_classic-later gem. See the documentation for # ActiveJob::QueueAdapters::QueueClassicAdapter. # diff --git a/activejob/lib/active_job/queue_adapters/inline_adapter.rb b/activejob/lib/active_job/queue_adapters/inline_adapter.rb index e498454909..08e26b7418 100644 --- a/activejob/lib/active_job/queue_adapters/inline_adapter.rb +++ b/activejob/lib/active_job/queue_adapters/inline_adapter.rb @@ -15,7 +15,7 @@ module ActiveJob end def enqueue_at(*) #:nodoc: - raise NotImplementedError.new("Use a queueing backend to enqueue jobs in the future. Read more at https://github.com/rails/activejob") + raise NotImplementedError.new("Use a queueing backend to enqueue jobs in the future. Read more at http://guides.rubyonrails.org/v4.2.0/active_job_basics.html") end end end diff --git a/activejob/lib/active_job/queue_adapters/qu_adapter.rb b/activejob/lib/active_job/queue_adapters/qu_adapter.rb index 7cdefefc02..30aa5a4670 100644 --- a/activejob/lib/active_job/queue_adapters/qu_adapter.rb +++ b/activejob/lib/active_job/queue_adapters/qu_adapter.rb @@ -6,11 +6,11 @@ module ActiveJob # # Qu is a Ruby library for queuing and processing background jobs. It is # heavily inspired by delayed_job and Resque. Qu was created to overcome - # some shortcomings in the existing queuing libraries that we experienced. + # some shortcomings in the existing queuing libraries. # The advantages of Qu are: Multiple backends (redis, mongo), jobs are # requeued when worker is killed, resque-like API. # - # Read more about Que {here}[https://github.com/bkeepers/qu]. + # Read more about Qu {here}[https://github.com/bkeepers/qu]. # # To use Qu set the queue_adapter config to +:qu+. # diff --git a/activejob/lib/active_job/queue_adapters/queue_classic_adapter.rb b/activejob/lib/active_job/queue_adapters/queue_classic_adapter.rb index bde20e037e..1a46f20420 100644 --- a/activejob/lib/active_job/queue_adapters/queue_classic_adapter.rb +++ b/activejob/lib/active_job/queue_adapters/queue_classic_adapter.rb @@ -2,7 +2,7 @@ require 'queue_classic' module ActiveJob module QueueAdapters - # == Queue Classic adapter for Active Job + # == queue_classic adapter for Active Job # # queue_classic provides a simple interface to a PostgreSQL-backed message # queue. queue_classic specializes in concurrent locking and minimizing @@ -11,9 +11,9 @@ module ActiveJob # production environment and that adding another dependency (e.g. redis, # beanstalkd, 0mq) is undesirable. # - # Read more about Queue Classic {here}[https://github.com/ryandotsmith/queue_classic]. + # Read more about queue_classic {here}[https://github.com/QueueClassic/queue_classic]. # - # To use Queue Classic set the queue_adapter config to +:queue_classic+. + # To use queue_classic set the queue_adapter config to +:queue_classic+. # # Rails.application.config.active_job.queue_adapter = :queue_classic class QueueClassicAdapter @@ -25,7 +25,7 @@ module ActiveJob def enqueue_at(job, timestamp) #:nodoc: queue = build_queue(job.queue_name) unless queue.respond_to?(:enqueue_at) - raise NotImplementedError, 'To be able to schedule jobs with Queue Classic ' \ + raise NotImplementedError, 'To be able to schedule jobs with queue_classic ' \ 'the QC::Queue needs to respond to `enqueue_at(timestamp, method, *args)`. ' 'You can implement this yourself or you can use the queue_classic-later gem.' end @@ -34,7 +34,7 @@ module ActiveJob # Builds a <tt>QC::Queue</tt> object to schedule jobs on. # - # If you have a custom <tt>QC::Queue</tt> subclass you'll need to suclass + # If you have a custom <tt>QC::Queue</tt> subclass you'll need to subclass # <tt>ActiveJob::QueueAdapters::QueueClassicAdapter</tt> and override the # <tt>build_queue</tt> method. def build_queue(queue_name) diff --git a/activejob/lib/active_job/queue_adapters/sidekiq_adapter.rb b/activejob/lib/active_job/queue_adapters/sidekiq_adapter.rb index 74655cf0ca..21005fc728 100644 --- a/activejob/lib/active_job/queue_adapters/sidekiq_adapter.rb +++ b/activejob/lib/active_job/queue_adapters/sidekiq_adapter.rb @@ -6,8 +6,8 @@ module ActiveJob # # Simple, efficient background processing for Ruby. Sidekiq uses threads to # handle many jobs at the same time in the same process. It does not - # require Rails but will integrate tightly with Rails 3/4 to make - # background processing dead simple. + # require Rails but will integrate tightly with it to make background + # processing dead simple. # # Read more about Sidekiq {here}[http://sidekiq.org]. # @@ -21,8 +21,7 @@ module ActiveJob Sidekiq::Client.push \ 'class' => JobWrapper, 'queue' => job.queue_name, - 'args' => [ job.serialize ], - 'retry' => true + 'args' => [ job.serialize ] end def enqueue_at(job, timestamp) #:nodoc: @@ -30,7 +29,6 @@ module ActiveJob 'class' => JobWrapper, 'queue' => job.queue_name, 'args' => [ job.serialize ], - 'retry' => true, 'at' => timestamp end end diff --git a/activejob/lib/active_job/queue_name.rb b/activejob/lib/active_job/queue_name.rb index 45acb71605..d167617e4e 100644 --- a/activejob/lib/active_job/queue_name.rb +++ b/activejob/lib/active_job/queue_name.rb @@ -6,6 +6,15 @@ module ActiveJob mattr_accessor(:queue_name_prefix) mattr_accessor(:default_queue_name) { "default" } + # Specifies the name of the queue to process the job on. + # + # class PublishToFeedJob < ActiveJob::Base + # queue_as :feeds + # + # def perform(post) + # post.to_feed! + # end + # end def queue_as(part_name=nil, &block) if block_given? self.queue_name = block @@ -15,7 +24,7 @@ module ActiveJob end def queue_name_from_part(part_name) #:nodoc: - queue_name = part_name.to_s.presence || default_queue_name + queue_name = part_name || default_queue_name name_parts = [queue_name_prefix.presence, queue_name] name_parts.compact.join('_') end diff --git a/activejob/lib/active_job/test_helper.rb b/activejob/lib/active_job/test_helper.rb index fa0576669e..af62fae9b9 100644 --- a/activejob/lib/active_job/test_helper.rb +++ b/activejob/lib/active_job/test_helper.rb @@ -150,7 +150,7 @@ module ActiveJob matching_job = enqueued_jobs.any? do |job| args.all? { |key, value| value == job[key] } end - assert matching_job + assert matching_job, "No enqueued job found with #{args}" ensure queue_adapter.enqueued_jobs = original_enqueued_jobs + enqueued_jobs end |