activejob_backport 0.0.1

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 +1 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.md +17 -0
  5. data/lib/active_job.rb +39 -0
  6. data/lib/active_job/arguments.rb +81 -0
  7. data/lib/active_job/base.rb +21 -0
  8. data/lib/active_job/callbacks.rb +144 -0
  9. data/lib/active_job/configured_job.rb +16 -0
  10. data/lib/active_job/core.rb +89 -0
  11. data/lib/active_job/enqueuing.rb +75 -0
  12. data/lib/active_job/execution.rb +41 -0
  13. data/lib/active_job/gem_version.rb +15 -0
  14. data/lib/active_job/logging.rb +121 -0
  15. data/lib/active_job/queue_adapter.rb +29 -0
  16. data/lib/active_job/queue_adapters.rb +17 -0
  17. data/lib/active_job/queue_adapters/backburner_adapter.rb +26 -0
  18. data/lib/active_job/queue_adapters/delayed_job_adapter.rb +23 -0
  19. data/lib/active_job/queue_adapters/inline_adapter.rb +15 -0
  20. data/lib/active_job/queue_adapters/qu_adapter.rb +29 -0
  21. data/lib/active_job/queue_adapters/que_adapter.rb +23 -0
  22. data/lib/active_job/queue_adapters/queue_classic_adapter.rb +40 -0
  23. data/lib/active_job/queue_adapters/resque_adapter.rb +41 -0
  24. data/lib/active_job/queue_adapters/sidekiq_adapter.rb +35 -0
  25. data/lib/active_job/queue_adapters/sneakers_adapter.rb +34 -0
  26. data/lib/active_job/queue_adapters/sucker_punch_adapter.rb +25 -0
  27. data/lib/active_job/queue_adapters/test_adapter.rb +37 -0
  28. data/lib/active_job/queue_name.rb +39 -0
  29. data/lib/active_job/railtie.rb +23 -0
  30. data/lib/active_job/test_case.rb +7 -0
  31. data/lib/active_job/test_helper.rb +196 -0
  32. data/lib/active_job/version.rb +8 -0
  33. data/lib/activejob_backport.rb +1 -0
  34. data/lib/global_id.rb +6 -0
  35. data/lib/global_id/global_id.rb +93 -0
  36. data/lib/global_id/identification.rb +13 -0
  37. data/lib/global_id/locator.rb +83 -0
  38. data/lib/rails/generators/job/job_generator.rb +24 -0
  39. data/lib/rails/generators/job/templates/job.rb +9 -0
  40. metadata +124 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2d443ef108536b2070d997a09d65c038ce0d67f1
4
+ data.tar.gz: 222e88e76594124766adefcad4b53195d33b8a2e
5
+ SHA512:
6
+ metadata.gz: 24e46886f1267b394bb8278352c005cf2eb2ed9930b1f674abe8d3f0dd0f26a4317e0bd94052b9ce2eb2bfcf32325611f0a85abf9745516a37a773fee5c05882
7
+ data.tar.gz: 2f827a68356e4e15d563658b0b3522ff7c637a377bfc1978da2216e06eb921ff0b0e21a5c62e9ed6cc3d6e9d972be1564390d67e957d4240c7b3f405a89e9286
data/CHANGELOG.md ADDED
@@ -0,0 +1 @@
1
+ * Started project.
data/MIT-LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2014 David Heinemeier Hansson
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
data/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # Active Job
2
+
3
+ Active Job backported to Rails 4.0 and 4.1
4
+
5
+ ```ruby
6
+ gem 'activejob_backport'
7
+ ```
8
+
9
+ And create `config/initializers/active_job.rb` with:
10
+
11
+ ```ruby
12
+ ActiveJob::Base.queue_adapter = :inline # default queue adapter
13
+ # Adapters currently supported: :backburner, :delayed_job, :qu, :que, :queue_classic,
14
+ # :resque, :sidekiq, :sneakers, :sucker_punch
15
+ ```
16
+
17
+ See [how to use Active Job](http://edgeguides.rubyonrails.org/active_job_basics.html) and the [official repo](https://github.com/rails/rails/tree/master/activejob)
data/lib/active_job.rb ADDED
@@ -0,0 +1,39 @@
1
+ #--
2
+ # Copyright (c) 2014 David Heinemeier Hansson
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ require 'active_support'
25
+ require 'active_support/rails'
26
+ require 'active_job/version'
27
+ require 'global_id' if !defined?(GlobalId)
28
+ require 'active_job/railtie' if defined?(Rails)
29
+ require 'active_support/core_ext/module/attribute_accessors'
30
+
31
+ module ActiveJob
32
+ extend ActiveSupport::Autoload
33
+
34
+ autoload :Base
35
+ autoload :QueueAdapters
36
+ autoload :ConfiguredJob
37
+ autoload :TestCase
38
+ autoload :TestHelper
39
+ end
@@ -0,0 +1,81 @@
1
+ module ActiveJob
2
+ # Raised when an exception is raised during job arguments deserialization.
3
+ #
4
+ # Wraps the original exception raised as +original_exception+.
5
+ class DeserializationError < StandardError
6
+ attr_reader :original_exception
7
+
8
+ def initialize(e) #:nodoc:
9
+ super("Error while trying to deserialize arguments: #{e.message}")
10
+ @original_exception = e
11
+ set_backtrace e.backtrace
12
+ end
13
+ end
14
+
15
+ # Raised when an unsupported argument type is being set as job argument. We
16
+ # currently support NilClass, Fixnum, Float, String, TrueClass, FalseClass,
17
+ # Bignum and object that can be represented as GlobalIDs (ex: Active Record).
18
+ # Also raised if you set the key for a Hash something else than a string or
19
+ # a symbol.
20
+ class SerializationError < ArgumentError
21
+ end
22
+
23
+ module Arguments
24
+ extend self
25
+ TYPE_WHITELIST = [ NilClass, Fixnum, Float, String, TrueClass, FalseClass, Bignum ]
26
+
27
+ def serialize(arguments)
28
+ arguments.map { |argument| serialize_argument(argument) }
29
+ end
30
+
31
+ def deserialize(arguments)
32
+ arguments.map { |argument| deserialize_argument(argument) }
33
+ rescue => e
34
+ raise DeserializationError.new(e)
35
+ end
36
+
37
+ private
38
+ def serialize_argument(argument)
39
+ case argument
40
+ when *TYPE_WHITELIST
41
+ argument
42
+ when GlobalID::Identification
43
+ argument.to_global_id.to_s
44
+ when Array
45
+ argument.map { |arg| serialize_argument(arg) }
46
+ when Hash
47
+ argument.each_with_object({}) do |(key, value), hash|
48
+ hash[serialize_hash_key(key)] = serialize_argument(value)
49
+ end
50
+ else
51
+ raise SerializationError.new("Unsupported argument type: #{argument.class.name}")
52
+ end
53
+ end
54
+
55
+ def deserialize_argument(argument)
56
+ case argument
57
+ when String
58
+ GlobalID::Locator.locate(argument) || argument
59
+ when *TYPE_WHITELIST
60
+ argument
61
+ when Array
62
+ argument.map { |arg| deserialize_argument(arg) }
63
+ when Hash
64
+ argument.each_with_object({}.with_indifferent_access) do |(key, value), hash|
65
+ hash[key] = deserialize_argument(value)
66
+ end
67
+ else
68
+ raise ArgumentError, "Can only deserialize primitive arguments: #{argument.inspect}"
69
+ end
70
+ end
71
+
72
+ def serialize_hash_key(key)
73
+ case key
74
+ when String, Symbol
75
+ key.to_s
76
+ else
77
+ raise SerializationError.new("Only string and symbol hash keys may be serialized as job arguments, but #{key.inspect} is a #{key.class}")
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,21 @@
1
+ require 'active_job/core'
2
+ require 'active_job/queue_adapter'
3
+ require 'active_job/queue_name'
4
+ require 'active_job/enqueuing'
5
+ require 'active_job/execution'
6
+ require 'active_job/callbacks'
7
+ require 'active_job/logging'
8
+
9
+ module ActiveJob
10
+ class Base
11
+ include Core
12
+ include QueueAdapter
13
+ include QueueName
14
+ include Enqueuing
15
+ include Execution
16
+ include Callbacks
17
+ include Logging
18
+
19
+ ActiveSupport.run_load_hooks(:active_job, self)
20
+ end
21
+ end
@@ -0,0 +1,144 @@
1
+ require 'active_support/callbacks'
2
+
3
+ module ActiveJob
4
+ # = Active Job Callbacks
5
+ #
6
+ # Active Job provides hooks during the lifecycle of a job. Callbacks allow you
7
+ # to trigger logic during the lifecycle of a job. Available callbacks are:
8
+ #
9
+ # * <tt>before_enqueue</tt>
10
+ # * <tt>around_enqueue</tt>
11
+ # * <tt>after_enqueue</tt>
12
+ # * <tt>before_perform</tt>
13
+ # * <tt>around_perform</tt>
14
+ # * <tt>after_perform</tt>
15
+ #
16
+ module Callbacks
17
+ extend ActiveSupport::Concern
18
+ include ActiveSupport::Callbacks
19
+
20
+ included do
21
+ define_callbacks :perform
22
+ define_callbacks :enqueue
23
+ end
24
+
25
+ module ClassMethods
26
+ # Defines a callback that will get called right before the
27
+ # job's perform method is executed.
28
+ #
29
+ # class VideoProcessJob < ActiveJob::Base
30
+ # queue_as :default
31
+ #
32
+ # before_perform do |job|
33
+ # UserMailer.notify_video_started_processing(job.arguments.first)
34
+ # end
35
+ #
36
+ # def perform(video_id)
37
+ # Video.find(video_id).process
38
+ # end
39
+ # end
40
+ #
41
+ def before_perform(*filters, &blk)
42
+ set_callback(:perform, :before, *filters, &blk)
43
+ end
44
+
45
+ # Defines a callback that will get called right after the
46
+ # job's perform method has finished.
47
+ #
48
+ # class VideoProcessJob < ActiveJob::Base
49
+ # queue_as :default
50
+ #
51
+ # after_perform do |job|
52
+ # UserMailer.notify_video_processed(job.arguments.first)
53
+ # end
54
+ #
55
+ # def perform(video_id)
56
+ # Video.find(video_id).process
57
+ # end
58
+ # end
59
+ #
60
+ def after_perform(*filters, &blk)
61
+ set_callback(:perform, :after, *filters, &blk)
62
+ end
63
+
64
+ # Defines a callback that will get called around the job's perform method.
65
+ #
66
+ # class VideoProcessJob < ActiveJob::Base
67
+ # queue_as :default
68
+ #
69
+ # around_perform do |job, block|
70
+ # UserMailer.notify_video_started_processing(job.arguments.first)
71
+ # block.call
72
+ # UserMailer.notify_video_processed(job.arguments.first)
73
+ # end
74
+ #
75
+ # def perform(video_id)
76
+ # Video.find(video_id).process
77
+ # end
78
+ # end
79
+ #
80
+ def around_perform(*filters, &blk)
81
+ set_callback(:perform, :around, *filters, &blk)
82
+ end
83
+
84
+ # Defines a callback that will get called right before the
85
+ # job is enqueued.
86
+ #
87
+ # class VideoProcessJob < ActiveJob::Base
88
+ # queue_as :default
89
+ #
90
+ # before_enqueue do |job|
91
+ # $statsd.increment "enqueue-video-job.try"
92
+ # end
93
+ #
94
+ # def perform(video_id)
95
+ # Video.find(video_id).process
96
+ # end
97
+ # end
98
+ #
99
+ def before_enqueue(*filters, &blk)
100
+ set_callback(:enqueue, :before, *filters, &blk)
101
+ end
102
+
103
+ # Defines a callback that will get called right after the
104
+ # job is enqueued.
105
+ #
106
+ # class VideoProcessJob < ActiveJob::Base
107
+ # queue_as :default
108
+ #
109
+ # after_enqueue do |job|
110
+ # $statsd.increment "enqueue-video-job.success"
111
+ # end
112
+ #
113
+ # def perform(video_id)
114
+ # Video.find(video_id).process
115
+ # end
116
+ # end
117
+ #
118
+ def after_enqueue(*filters, &blk)
119
+ set_callback(:enqueue, :after, *filters, &blk)
120
+ end
121
+
122
+ # Defines a callback that will get called before and after the
123
+ # job is enqueued.
124
+ #
125
+ # class VideoProcessJob < ActiveJob::Base
126
+ # queue_as :default
127
+ #
128
+ # around_enqueue do |job, block|
129
+ # $statsd.time "video-job.process" do
130
+ # block.call
131
+ # end
132
+ # end
133
+ #
134
+ # def perform(video_id)
135
+ # Video.find(video_id).process
136
+ # end
137
+ # end
138
+ #
139
+ def around_enqueue(*filters, &blk)
140
+ set_callback(:enqueue, :around, *filters, &blk)
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,16 @@
1
+ module ActiveJob
2
+ class ConfiguredJob #:nodoc:
3
+ def initialize(job_class, options={})
4
+ @options = options
5
+ @job_class = job_class
6
+ end
7
+
8
+ def perform_now(*args)
9
+ @job_class.new(*args).perform_now
10
+ end
11
+
12
+ def perform_later(*args)
13
+ @job_class.new(*args).enqueue @options
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,89 @@
1
+ module ActiveJob
2
+ module Core
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ # Job arguments
7
+ attr_accessor :arguments
8
+ attr_writer :serialized_arguments
9
+
10
+ # Timestamp when the job should be performed
11
+ attr_accessor :scheduled_at
12
+
13
+ # Job Identifier
14
+ attr_accessor :job_id
15
+
16
+ # Queue on which the job should be run on.
17
+ attr_writer :queue_name
18
+ end
19
+
20
+ module ClassMethods
21
+ # Creates a new job instance from a hash created with +serialize+
22
+ def deserialize(job_data)
23
+ job = job_data['job_class'].constantize.new
24
+ job.job_id = job_data['job_id']
25
+ job.queue_name = job_data['queue_name']
26
+ job.serialized_arguments = job_data['arguments']
27
+ job
28
+ end
29
+
30
+ # Creates a job preconfigured with the given options. You can call
31
+ # perform_later with the job arguments to enqueue the job with the
32
+ # preconfigured options
33
+ #
34
+ # ==== Options
35
+ # * <tt>:wait</tt> - Enqueues the job with the specified delay
36
+ # * <tt>:wait_until</tt> - Enqueues the job at the time specified
37
+ # * <tt>:queue</tt> - Enqueues the job on the specified queue
38
+ #
39
+ # ==== Examples
40
+ #
41
+ # VideoJob.set(queue: :some_queue).perform_later(Video.last)
42
+ # VideoJob.set(wait: 5.minutes).perform_later(Video.last)
43
+ # VideoJob.set(wait_until: Time.tomorroe).perform_later(Video.last)
44
+ # VideoJob.set(queue: :some_queue, wait: 5.minutes).perform_later(Video.last)
45
+ # VideoJob.set(queue: :some_queue, wait_until: Time.tomorroe).perform_later(Video.last)
46
+ def set(options={})
47
+ ConfiguredJob.new(self, options)
48
+ end
49
+ end
50
+
51
+ # Creates a new job instance. Takes as arguments the arguments that
52
+ # will be passed to the perform method.
53
+ def initialize(*arguments)
54
+ @arguments = arguments
55
+ @job_id = SecureRandom.uuid
56
+ @queue_name = self.class.queue_name
57
+ end
58
+
59
+ # Returns a hash with the job data that can safely be passed to the
60
+ # queueing adapter.
61
+ def serialize
62
+ {
63
+ 'job_class' => self.class.name,
64
+ 'job_id' => job_id,
65
+ 'queue_name' => queue_name,
66
+ 'arguments' => serialize_arguments(arguments)
67
+ }
68
+ end
69
+
70
+ private
71
+ def deserialize_arguments_if_needed
72
+ if defined?(@serialized_arguments) && @serialized_arguments.present?
73
+ @arguments = deserialize_arguments(@serialized_arguments)
74
+ @serialized_arguments = nil
75
+ end
76
+ end
77
+
78
+ def serialize_arguments(serialized_args)
79
+ Arguments.serialize(serialized_args)
80
+ end
81
+
82
+ def deserialize_arguments(serialized_args)
83
+ Arguments.deserialize(serialized_args)
84
+ end
85
+ end
86
+ end
87
+
88
+
89
+