activejob 5.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +80 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.md +126 -0
  5. data/lib/active_job.rb +39 -0
  6. data/lib/active_job/arguments.rb +165 -0
  7. data/lib/active_job/base.rb +74 -0
  8. data/lib/active_job/callbacks.rb +155 -0
  9. data/lib/active_job/configured_job.rb +18 -0
  10. data/lib/active_job/core.rb +158 -0
  11. data/lib/active_job/enqueuing.rb +59 -0
  12. data/lib/active_job/exceptions.rb +134 -0
  13. data/lib/active_job/execution.rb +49 -0
  14. data/lib/active_job/gem_version.rb +17 -0
  15. data/lib/active_job/logging.rb +130 -0
  16. data/lib/active_job/queue_adapter.rb +60 -0
  17. data/lib/active_job/queue_adapters.rb +139 -0
  18. data/lib/active_job/queue_adapters/async_adapter.rb +116 -0
  19. data/lib/active_job/queue_adapters/backburner_adapter.rb +36 -0
  20. data/lib/active_job/queue_adapters/delayed_job_adapter.rb +47 -0
  21. data/lib/active_job/queue_adapters/inline_adapter.rb +23 -0
  22. data/lib/active_job/queue_adapters/qu_adapter.rb +46 -0
  23. data/lib/active_job/queue_adapters/que_adapter.rb +39 -0
  24. data/lib/active_job/queue_adapters/queue_classic_adapter.rb +58 -0
  25. data/lib/active_job/queue_adapters/resque_adapter.rb +53 -0
  26. data/lib/active_job/queue_adapters/sidekiq_adapter.rb +47 -0
  27. data/lib/active_job/queue_adapters/sneakers_adapter.rb +48 -0
  28. data/lib/active_job/queue_adapters/sucker_punch_adapter.rb +49 -0
  29. data/lib/active_job/queue_adapters/test_adapter.rb +67 -0
  30. data/lib/active_job/queue_name.rb +49 -0
  31. data/lib/active_job/queue_priority.rb +43 -0
  32. data/lib/active_job/railtie.rb +34 -0
  33. data/lib/active_job/test_case.rb +11 -0
  34. data/lib/active_job/test_helper.rb +456 -0
  35. data/lib/active_job/translation.rb +13 -0
  36. data/lib/active_job/version.rb +10 -0
  37. data/lib/rails/generators/job/job_generator.rb +40 -0
  38. data/lib/rails/generators/job/templates/application_job.rb.tt +9 -0
  39. data/lib/rails/generators/job/templates/job.rb.tt +9 -0
  40. 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