activejob 5.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +80 -0
- data/MIT-LICENSE +21 -0
- data/README.md +126 -0
- data/lib/active_job.rb +39 -0
- data/lib/active_job/arguments.rb +165 -0
- data/lib/active_job/base.rb +74 -0
- data/lib/active_job/callbacks.rb +155 -0
- data/lib/active_job/configured_job.rb +18 -0
- data/lib/active_job/core.rb +158 -0
- data/lib/active_job/enqueuing.rb +59 -0
- data/lib/active_job/exceptions.rb +134 -0
- data/lib/active_job/execution.rb +49 -0
- data/lib/active_job/gem_version.rb +17 -0
- data/lib/active_job/logging.rb +130 -0
- data/lib/active_job/queue_adapter.rb +60 -0
- data/lib/active_job/queue_adapters.rb +139 -0
- data/lib/active_job/queue_adapters/async_adapter.rb +116 -0
- data/lib/active_job/queue_adapters/backburner_adapter.rb +36 -0
- data/lib/active_job/queue_adapters/delayed_job_adapter.rb +47 -0
- data/lib/active_job/queue_adapters/inline_adapter.rb +23 -0
- data/lib/active_job/queue_adapters/qu_adapter.rb +46 -0
- data/lib/active_job/queue_adapters/que_adapter.rb +39 -0
- data/lib/active_job/queue_adapters/queue_classic_adapter.rb +58 -0
- data/lib/active_job/queue_adapters/resque_adapter.rb +53 -0
- data/lib/active_job/queue_adapters/sidekiq_adapter.rb +47 -0
- data/lib/active_job/queue_adapters/sneakers_adapter.rb +48 -0
- data/lib/active_job/queue_adapters/sucker_punch_adapter.rb +49 -0
- data/lib/active_job/queue_adapters/test_adapter.rb +67 -0
- data/lib/active_job/queue_name.rb +49 -0
- data/lib/active_job/queue_priority.rb +43 -0
- data/lib/active_job/railtie.rb +34 -0
- data/lib/active_job/test_case.rb +11 -0
- data/lib/active_job/test_helper.rb +456 -0
- data/lib/active_job/translation.rb +13 -0
- data/lib/active_job/version.rb +10 -0
- data/lib/rails/generators/job/job_generator.rb +40 -0
- data/lib/rails/generators/job/templates/application_job.rb.tt +9 -0
- data/lib/rails/generators/job/templates/job.rb.tt +9 -0
- metadata +110 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "backburner"
|
4
|
+
|
5
|
+
module ActiveJob
|
6
|
+
module QueueAdapters
|
7
|
+
# == Backburner adapter for Active Job
|
8
|
+
#
|
9
|
+
# Backburner is a beanstalkd-powered job queue that can handle a very
|
10
|
+
# high volume of jobs. You create background jobs and place them on
|
11
|
+
# multiple work queues to be processed later. Read more about
|
12
|
+
# Backburner {here}[https://github.com/nesquena/backburner].
|
13
|
+
#
|
14
|
+
# To use Backburner set the queue_adapter config to +:backburner+.
|
15
|
+
#
|
16
|
+
# Rails.application.config.active_job.queue_adapter = :backburner
|
17
|
+
class BackburnerAdapter
|
18
|
+
def enqueue(job) #:nodoc:
|
19
|
+
Backburner::Worker.enqueue JobWrapper, [ job.serialize ], queue: job.queue_name
|
20
|
+
end
|
21
|
+
|
22
|
+
def enqueue_at(job, timestamp) #:nodoc:
|
23
|
+
delay = timestamp - Time.current.to_f
|
24
|
+
Backburner::Worker.enqueue JobWrapper, [ job.serialize ], queue: job.queue_name, delay: delay
|
25
|
+
end
|
26
|
+
|
27
|
+
class JobWrapper #:nodoc:
|
28
|
+
class << self
|
29
|
+
def perform(job_data)
|
30
|
+
Base.execute job_data
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "delayed_job"
|
4
|
+
|
5
|
+
module ActiveJob
|
6
|
+
module QueueAdapters
|
7
|
+
# == Delayed Job adapter for Active Job
|
8
|
+
#
|
9
|
+
# Delayed::Job (or DJ) encapsulates the common pattern of asynchronously
|
10
|
+
# executing longer tasks in the background. Although DJ can have many
|
11
|
+
# storage backends, one of the most used is based on Active Record.
|
12
|
+
# Read more about Delayed Job {here}[https://github.com/collectiveidea/delayed_job].
|
13
|
+
#
|
14
|
+
# To use Delayed Job, set the queue_adapter config to +:delayed_job+.
|
15
|
+
#
|
16
|
+
# Rails.application.config.active_job.queue_adapter = :delayed_job
|
17
|
+
class DelayedJobAdapter
|
18
|
+
def enqueue(job) #:nodoc:
|
19
|
+
delayed_job = Delayed::Job.enqueue(JobWrapper.new(job.serialize), queue: job.queue_name, priority: job.priority)
|
20
|
+
job.provider_job_id = delayed_job.id
|
21
|
+
delayed_job
|
22
|
+
end
|
23
|
+
|
24
|
+
def enqueue_at(job, timestamp) #:nodoc:
|
25
|
+
delayed_job = Delayed::Job.enqueue(JobWrapper.new(job.serialize), queue: job.queue_name, priority: job.priority, run_at: Time.at(timestamp))
|
26
|
+
job.provider_job_id = delayed_job.id
|
27
|
+
delayed_job
|
28
|
+
end
|
29
|
+
|
30
|
+
class JobWrapper #:nodoc:
|
31
|
+
attr_accessor :job_data
|
32
|
+
|
33
|
+
def initialize(job_data)
|
34
|
+
@job_data = job_data
|
35
|
+
end
|
36
|
+
|
37
|
+
def display_name
|
38
|
+
"#{job_data['job_class']} [#{job_data['job_id']}] from DelayedJob(#{job_data['queue_name']}) with arguments: #{job_data['arguments']}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def perform
|
42
|
+
Base.execute(job_data)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveJob
|
4
|
+
module QueueAdapters
|
5
|
+
# == Active Job Inline adapter
|
6
|
+
#
|
7
|
+
# When enqueuing jobs with the Inline adapter the job will be executed
|
8
|
+
# immediately.
|
9
|
+
#
|
10
|
+
# To use the Inline set the queue_adapter config to +:inline+.
|
11
|
+
#
|
12
|
+
# Rails.application.config.active_job.queue_adapter = :inline
|
13
|
+
class InlineAdapter
|
14
|
+
def enqueue(job) #:nodoc:
|
15
|
+
Base.execute(job.serialize)
|
16
|
+
end
|
17
|
+
|
18
|
+
def enqueue_at(*) #:nodoc:
|
19
|
+
raise NotImplementedError, "Use a queueing backend to enqueue jobs in the future. Read more at http://guides.rubyonrails.org/active_job_basics.html"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "qu"
|
4
|
+
|
5
|
+
module ActiveJob
|
6
|
+
module QueueAdapters
|
7
|
+
# == Qu adapter for Active Job
|
8
|
+
#
|
9
|
+
# Qu is a Ruby library for queuing and processing background jobs. It is
|
10
|
+
# heavily inspired by delayed_job and Resque. Qu was created to overcome
|
11
|
+
# some shortcomings in the existing queuing libraries.
|
12
|
+
# The advantages of Qu are: Multiple backends (redis, mongo), jobs are
|
13
|
+
# requeued when worker is killed, resque-like API.
|
14
|
+
#
|
15
|
+
# Read more about Qu {here}[https://github.com/bkeepers/qu].
|
16
|
+
#
|
17
|
+
# To use Qu set the queue_adapter config to +:qu+.
|
18
|
+
#
|
19
|
+
# Rails.application.config.active_job.queue_adapter = :qu
|
20
|
+
class QuAdapter
|
21
|
+
def enqueue(job, *args) #:nodoc:
|
22
|
+
qu_job = Qu::Payload.new(klass: JobWrapper, args: [job.serialize]).tap do |payload|
|
23
|
+
payload.instance_variable_set(:@queue, job.queue_name)
|
24
|
+
end.push
|
25
|
+
|
26
|
+
# qu_job can be nil depending on the configured backend
|
27
|
+
job.provider_job_id = qu_job.id unless qu_job.nil?
|
28
|
+
qu_job
|
29
|
+
end
|
30
|
+
|
31
|
+
def enqueue_at(job, timestamp, *args) #:nodoc:
|
32
|
+
raise NotImplementedError, "This queueing backend does not support scheduling jobs. To see what features are supported go to http://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html"
|
33
|
+
end
|
34
|
+
|
35
|
+
class JobWrapper < Qu::Job #:nodoc:
|
36
|
+
def initialize(job_data)
|
37
|
+
@job_data = job_data
|
38
|
+
end
|
39
|
+
|
40
|
+
def perform
|
41
|
+
Base.execute @job_data
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "que"
|
4
|
+
|
5
|
+
module ActiveJob
|
6
|
+
module QueueAdapters
|
7
|
+
# == Que adapter for Active Job
|
8
|
+
#
|
9
|
+
# Que is a high-performance alternative to DelayedJob or QueueClassic that
|
10
|
+
# improves the reliability of your application by protecting your jobs with
|
11
|
+
# the same ACID guarantees as the rest of your data. Que is a queue for
|
12
|
+
# Ruby and PostgreSQL that manages jobs using advisory locks.
|
13
|
+
#
|
14
|
+
# Read more about Que {here}[https://github.com/chanks/que].
|
15
|
+
#
|
16
|
+
# To use Que set the queue_adapter config to +:que+.
|
17
|
+
#
|
18
|
+
# Rails.application.config.active_job.queue_adapter = :que
|
19
|
+
class QueAdapter
|
20
|
+
def enqueue(job) #:nodoc:
|
21
|
+
que_job = JobWrapper.enqueue job.serialize, priority: job.priority
|
22
|
+
job.provider_job_id = que_job.attrs["job_id"]
|
23
|
+
que_job
|
24
|
+
end
|
25
|
+
|
26
|
+
def enqueue_at(job, timestamp) #:nodoc:
|
27
|
+
que_job = JobWrapper.enqueue job.serialize, priority: job.priority, run_at: Time.at(timestamp)
|
28
|
+
job.provider_job_id = que_job.attrs["job_id"]
|
29
|
+
que_job
|
30
|
+
end
|
31
|
+
|
32
|
+
class JobWrapper < Que::Job #:nodoc:
|
33
|
+
def run(job_data)
|
34
|
+
Base.execute job_data
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "queue_classic"
|
4
|
+
|
5
|
+
module ActiveJob
|
6
|
+
module QueueAdapters
|
7
|
+
# == queue_classic adapter for Active Job
|
8
|
+
#
|
9
|
+
# queue_classic provides a simple interface to a PostgreSQL-backed message
|
10
|
+
# queue. queue_classic specializes in concurrent locking and minimizing
|
11
|
+
# database load while providing a simple, intuitive developer experience.
|
12
|
+
# queue_classic assumes that you are already using PostgreSQL in your
|
13
|
+
# production environment and that adding another dependency (e.g. redis,
|
14
|
+
# beanstalkd, 0mq) is undesirable.
|
15
|
+
#
|
16
|
+
# Read more about queue_classic {here}[https://github.com/QueueClassic/queue_classic].
|
17
|
+
#
|
18
|
+
# To use queue_classic set the queue_adapter config to +:queue_classic+.
|
19
|
+
#
|
20
|
+
# Rails.application.config.active_job.queue_adapter = :queue_classic
|
21
|
+
class QueueClassicAdapter
|
22
|
+
def enqueue(job) #:nodoc:
|
23
|
+
qc_job = build_queue(job.queue_name).enqueue("#{JobWrapper.name}.perform", job.serialize)
|
24
|
+
job.provider_job_id = qc_job["id"] if qc_job.is_a?(Hash)
|
25
|
+
qc_job
|
26
|
+
end
|
27
|
+
|
28
|
+
def enqueue_at(job, timestamp) #:nodoc:
|
29
|
+
queue = build_queue(job.queue_name)
|
30
|
+
unless queue.respond_to?(:enqueue_at)
|
31
|
+
raise NotImplementedError, "To be able to schedule jobs with queue_classic " \
|
32
|
+
"the QC::Queue needs to respond to `enqueue_at(timestamp, method, *args)`. " \
|
33
|
+
"You can implement this yourself or you can use the queue_classic-later gem."
|
34
|
+
end
|
35
|
+
qc_job = queue.enqueue_at(timestamp, "#{JobWrapper.name}.perform", job.serialize)
|
36
|
+
job.provider_job_id = qc_job["id"] if qc_job.is_a?(Hash)
|
37
|
+
qc_job
|
38
|
+
end
|
39
|
+
|
40
|
+
# Builds a <tt>QC::Queue</tt> object to schedule jobs on.
|
41
|
+
#
|
42
|
+
# If you have a custom <tt>QC::Queue</tt> subclass you'll need to subclass
|
43
|
+
# <tt>ActiveJob::QueueAdapters::QueueClassicAdapter</tt> and override the
|
44
|
+
# <tt>build_queue</tt> method.
|
45
|
+
def build_queue(queue_name)
|
46
|
+
QC::Queue.new(queue_name)
|
47
|
+
end
|
48
|
+
|
49
|
+
class JobWrapper #:nodoc:
|
50
|
+
class << self
|
51
|
+
def perform(job_data)
|
52
|
+
Base.execute job_data
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "resque"
|
4
|
+
require "active_support/core_ext/enumerable"
|
5
|
+
require "active_support/core_ext/array/access"
|
6
|
+
|
7
|
+
begin
|
8
|
+
require "resque-scheduler"
|
9
|
+
rescue LoadError
|
10
|
+
begin
|
11
|
+
require "resque_scheduler"
|
12
|
+
rescue LoadError
|
13
|
+
false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module ActiveJob
|
18
|
+
module QueueAdapters
|
19
|
+
# == Resque adapter for Active Job
|
20
|
+
#
|
21
|
+
# Resque (pronounced like "rescue") is a Redis-backed library for creating
|
22
|
+
# background jobs, placing those jobs on multiple queues, and processing
|
23
|
+
# them later.
|
24
|
+
#
|
25
|
+
# Read more about Resque {here}[https://github.com/resque/resque].
|
26
|
+
#
|
27
|
+
# To use Resque set the queue_adapter config to +:resque+.
|
28
|
+
#
|
29
|
+
# Rails.application.config.active_job.queue_adapter = :resque
|
30
|
+
class ResqueAdapter
|
31
|
+
def enqueue(job) #:nodoc:
|
32
|
+
JobWrapper.instance_variable_set(:@queue, job.queue_name)
|
33
|
+
Resque.enqueue_to job.queue_name, JobWrapper, job.serialize
|
34
|
+
end
|
35
|
+
|
36
|
+
def enqueue_at(job, timestamp) #:nodoc:
|
37
|
+
unless Resque.respond_to?(:enqueue_at_with_queue)
|
38
|
+
raise NotImplementedError, "To be able to schedule jobs with Resque you need the " \
|
39
|
+
"resque-scheduler gem. Please add it to your Gemfile and run bundle install"
|
40
|
+
end
|
41
|
+
Resque.enqueue_at_with_queue job.queue_name, timestamp, JobWrapper, job.serialize
|
42
|
+
end
|
43
|
+
|
44
|
+
class JobWrapper #:nodoc:
|
45
|
+
class << self
|
46
|
+
def perform(job_data)
|
47
|
+
Base.execute job_data
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "sidekiq"
|
4
|
+
|
5
|
+
module ActiveJob
|
6
|
+
module QueueAdapters
|
7
|
+
# == Sidekiq adapter for Active Job
|
8
|
+
#
|
9
|
+
# Simple, efficient background processing for Ruby. Sidekiq uses threads to
|
10
|
+
# handle many jobs at the same time in the same process. It does not
|
11
|
+
# require Rails but will integrate tightly with it to make background
|
12
|
+
# processing dead simple.
|
13
|
+
#
|
14
|
+
# Read more about Sidekiq {here}[http://sidekiq.org].
|
15
|
+
#
|
16
|
+
# To use Sidekiq set the queue_adapter config to +:sidekiq+.
|
17
|
+
#
|
18
|
+
# Rails.application.config.active_job.queue_adapter = :sidekiq
|
19
|
+
class SidekiqAdapter
|
20
|
+
def enqueue(job) #:nodoc:
|
21
|
+
# Sidekiq::Client does not support symbols as keys
|
22
|
+
job.provider_job_id = Sidekiq::Client.push \
|
23
|
+
"class" => JobWrapper,
|
24
|
+
"wrapped" => job.class.to_s,
|
25
|
+
"queue" => job.queue_name,
|
26
|
+
"args" => [ job.serialize ]
|
27
|
+
end
|
28
|
+
|
29
|
+
def enqueue_at(job, timestamp) #:nodoc:
|
30
|
+
job.provider_job_id = Sidekiq::Client.push \
|
31
|
+
"class" => JobWrapper,
|
32
|
+
"wrapped" => job.class.to_s,
|
33
|
+
"queue" => job.queue_name,
|
34
|
+
"args" => [ job.serialize ],
|
35
|
+
"at" => timestamp
|
36
|
+
end
|
37
|
+
|
38
|
+
class JobWrapper #:nodoc:
|
39
|
+
include Sidekiq::Worker
|
40
|
+
|
41
|
+
def perform(job_data)
|
42
|
+
Base.execute job_data.merge("provider_job_id" => jid)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "sneakers"
|
4
|
+
require "monitor"
|
5
|
+
|
6
|
+
module ActiveJob
|
7
|
+
module QueueAdapters
|
8
|
+
# == Sneakers adapter for Active Job
|
9
|
+
#
|
10
|
+
# A high-performance RabbitMQ background processing framework for Ruby.
|
11
|
+
# Sneakers is being used in production for both I/O and CPU intensive
|
12
|
+
# workloads, and have achieved the goals of high-performance and
|
13
|
+
# 0-maintenance, as designed.
|
14
|
+
#
|
15
|
+
# Read more about Sneakers {here}[https://github.com/jondot/sneakers].
|
16
|
+
#
|
17
|
+
# To use Sneakers set the queue_adapter config to +:sneakers+.
|
18
|
+
#
|
19
|
+
# Rails.application.config.active_job.queue_adapter = :sneakers
|
20
|
+
class SneakersAdapter
|
21
|
+
def initialize
|
22
|
+
@monitor = Monitor.new
|
23
|
+
end
|
24
|
+
|
25
|
+
def enqueue(job) #:nodoc:
|
26
|
+
@monitor.synchronize do
|
27
|
+
JobWrapper.from_queue job.queue_name
|
28
|
+
JobWrapper.enqueue ActiveSupport::JSON.encode(job.serialize)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def enqueue_at(job, timestamp) #:nodoc:
|
33
|
+
raise NotImplementedError, "This queueing backend does not support scheduling jobs. To see what features are supported go to http://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html"
|
34
|
+
end
|
35
|
+
|
36
|
+
class JobWrapper #:nodoc:
|
37
|
+
include Sneakers::Worker
|
38
|
+
from_queue "default"
|
39
|
+
|
40
|
+
def work(msg)
|
41
|
+
job_data = ActiveSupport::JSON.decode(msg)
|
42
|
+
Base.execute job_data
|
43
|
+
ack!
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "sucker_punch"
|
4
|
+
|
5
|
+
module ActiveJob
|
6
|
+
module QueueAdapters
|
7
|
+
# == Sucker Punch adapter for Active Job
|
8
|
+
#
|
9
|
+
# Sucker Punch is a single-process Ruby asynchronous processing library.
|
10
|
+
# This reduces the cost of hosting on a service like Heroku along
|
11
|
+
# with the memory footprint of having to maintain additional jobs if
|
12
|
+
# hosting on a dedicated server. All queues can run within a
|
13
|
+
# single application (eg. Rails, Sinatra, etc.) process.
|
14
|
+
#
|
15
|
+
# Read more about Sucker Punch {here}[https://github.com/brandonhilkert/sucker_punch].
|
16
|
+
#
|
17
|
+
# To use Sucker Punch set the queue_adapter config to +:sucker_punch+.
|
18
|
+
#
|
19
|
+
# Rails.application.config.active_job.queue_adapter = :sucker_punch
|
20
|
+
class SuckerPunchAdapter
|
21
|
+
def enqueue(job) #:nodoc:
|
22
|
+
if JobWrapper.respond_to?(:perform_async)
|
23
|
+
# sucker_punch 2.0 API
|
24
|
+
JobWrapper.perform_async job.serialize
|
25
|
+
else
|
26
|
+
# sucker_punch 1.0 API
|
27
|
+
JobWrapper.new.async.perform job.serialize
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def enqueue_at(job, timestamp) #:nodoc:
|
32
|
+
if JobWrapper.respond_to?(:perform_in)
|
33
|
+
delay = timestamp - Time.current.to_f
|
34
|
+
JobWrapper.perform_in delay, job.serialize
|
35
|
+
else
|
36
|
+
raise NotImplementedError, "sucker_punch 1.0 does not support `enqueued_at`. Please upgrade to version ~> 2.0.0 to enable this behavior."
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class JobWrapper #:nodoc:
|
41
|
+
include SuckerPunch::Job
|
42
|
+
|
43
|
+
def perform(job_data)
|
44
|
+
Base.execute job_data
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|