sidekiq_simple_delay 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8828bf73cab33678a8f4f1e0d8a2c51328fa74fd252737e9789ee7447f238e1c
4
- data.tar.gz: da61b4f204e3cfa49cec35d02689b9bc5fb19da5be5fcd67377508dc85945f80
3
+ metadata.gz: ec1fe6b079ffe00f678759842aabf1c0b541e963559ef96ffebd2a2ed320c8f1
4
+ data.tar.gz: a1539286fa1b0a82e25596d9a69741c601f5392c2a3372e811486f5adcd3af45
5
5
  SHA512:
6
- metadata.gz: e08fd24c781ae84862392ded431873e98fd519190331bf003f74bffc5ce43c64a83c72f3eb584eb8ada3196b157d2e519de733e7384d696bdc87a66d1a53bcf6
7
- data.tar.gz: e9f028312cbfc01d1f5d6219ac3ef6e8e09bf1936d042880da45142296306bbb385cc91a93dc53a014ac79350a00ef17c843ff391c8381c4432548a883e67a1e
6
+ metadata.gz: 6dd22a43966e73eb3adfdc5b9d3cd91158fa705f587368603a4edae954aedf713d619d32a03f1102002ae1f593eca25fba178d3984a0208e49b6973a7636ebc3
7
+ data.tar.gz: 024d186c564d19b6298bedddc0e5b0c2dd73ec7925c9c02a2fe04d706785354fab9162153284c8b14670329827ccf637a743d33b50b4fc375d1d009db9204a53
data/.circleci/config.yml CHANGED
@@ -26,7 +26,7 @@ spec_shared: &spec_shared
26
26
  --format RspecJunitFormatter \
27
27
  --out /tmp/test-results/rspec-basic.xml \
28
28
  --format progress \
29
- spec --tag ~enable_delay:true
29
+ spec --tag ~run_tag
30
30
 
31
31
  - run:
32
32
  name: Run enable_delay specs
@@ -35,7 +35,60 @@ spec_shared: &spec_shared
35
35
  --format RspecJunitFormatter \
36
36
  --out /tmp/test-results/rspec-basic.xml \
37
37
  --format progress \
38
- spec --tag enable_delay:true
38
+ spec --tag run_tag:enable_delay
39
+
40
+ - run:
41
+ name: Run active_record_base specs
42
+ command: |
43
+ bundle exec rspec --format progress \
44
+ --format RspecJunitFormatter \
45
+ --out /tmp/test-results/rspec-basic.xml \
46
+ --format progress \
47
+ spec --tag run_tag:active_record_base
48
+
49
+ - run:
50
+ name: Run application_record specs
51
+ command: |
52
+ bundle exec rspec --format progress \
53
+ --format RspecJunitFormatter \
54
+ --out /tmp/test-results/rspec-basic.xml \
55
+ --format progress \
56
+ spec --tag run_tag:application_record
57
+
58
+ - run:
59
+ name: Run active_record_single specs
60
+ command: |
61
+ bundle exec rspec --format progress \
62
+ --format RspecJunitFormatter \
63
+ --out /tmp/test-results/rspec-basic.xml \
64
+ --format progress \
65
+ spec --tag run_tag:active_record_single
66
+
67
+ - run:
68
+ name: Run action_mailer specs
69
+ command: |
70
+ bundle exec rspec --format progress \
71
+ --format RspecJunitFormatter \
72
+ --out /tmp/test-results/rspec-basic.xml \
73
+ --format progress \
74
+ spec --tag run_tag:action_mailer_base
75
+
76
+ - run:
77
+ name: Run application_mailer specs
78
+ command: |
79
+ bundle exec rspec --format progress \
80
+ --format RspecJunitFormatter \
81
+ --out /tmp/test-results/rspec-basic.xml \
82
+ --format progress \
83
+ spec --tag run_tag:application_mailer
84
+ - run:
85
+ name: Run action_mailer_single specs
86
+ command: |
87
+ bundle exec rspec --format progress \
88
+ --format RspecJunitFormatter \
89
+ --out /tmp/test-results/rspec-basic.xml \
90
+ --format progress \
91
+ spec --tag run_tag:action_mailer_single
39
92
 
40
93
  # collect reports
41
94
  - store_test_results:
data/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ # 0.2.0
2
+
3
+ * `simple_delay_spread`
4
+ * `ActiveRecord` integration
5
+ * `ActionMailer` integration
6
+
7
+ # 0.1.0
8
+
9
+ * `simple_delay`
10
+ * `simple_delay_for`
11
+ * `simple_delay_until`
data/Gemfile.lock CHANGED
@@ -1,12 +1,34 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sidekiq_simple_delay (0.1.0)
4
+ sidekiq_simple_delay (0.2.0)
5
5
  sidekiq
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
+ actionmailer (5.2.1.1)
11
+ actionpack (= 5.2.1.1)
12
+ actionview (= 5.2.1.1)
13
+ activejob (= 5.2.1.1)
14
+ mail (~> 2.5, >= 2.5.4)
15
+ rails-dom-testing (~> 2.0)
16
+ actionpack (5.2.1.1)
17
+ actionview (= 5.2.1.1)
18
+ activesupport (= 5.2.1.1)
19
+ rack (~> 2.0)
20
+ rack-test (>= 0.6.3)
21
+ rails-dom-testing (~> 2.0)
22
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
23
+ actionview (5.2.1.1)
24
+ activesupport (= 5.2.1.1)
25
+ builder (~> 3.1)
26
+ erubi (~> 1.4)
27
+ rails-dom-testing (~> 2.0)
28
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
29
+ activejob (5.2.1.1)
30
+ activesupport (= 5.2.1.1)
31
+ globalid (>= 0.3.6)
10
32
  activemodel (5.2.1.1)
11
33
  activesupport (= 5.2.1.1)
12
34
  activerecord (5.2.1.1)
@@ -20,18 +42,33 @@ GEM
20
42
  tzinfo (~> 1.1)
21
43
  arel (9.0.0)
22
44
  ast (2.4.0)
45
+ builder (3.2.3)
23
46
  bundler-audit (0.6.0)
24
47
  bundler (~> 1.2)
25
48
  thor (~> 0.18)
26
49
  concurrent-ruby (1.1.3)
27
50
  connection_pool (2.2.2)
51
+ crass (1.0.4)
52
+ database_cleaner (1.7.0)
28
53
  diff-lcs (1.3)
54
+ erubi (1.7.1)
29
55
  fakeredis (0.7.0)
30
56
  redis (>= 3.2, < 5.0)
57
+ globalid (0.4.1)
58
+ activesupport (>= 4.2.0)
31
59
  i18n (1.1.1)
32
60
  concurrent-ruby (~> 1.0)
33
61
  jaro_winkler (1.5.1)
62
+ loofah (2.2.3)
63
+ crass (~> 1.0.2)
64
+ nokogiri (>= 1.5.9)
65
+ mail (2.7.1)
66
+ mini_mime (>= 0.1.1)
67
+ mini_mime (1.0.1)
68
+ mini_portile2 (2.3.0)
34
69
  minitest (5.11.3)
70
+ nokogiri (1.8.5)
71
+ mini_portile2 (~> 2.3.0)
35
72
  parallel (1.12.1)
36
73
  parser (2.5.3.0)
37
74
  ast (~> 2.4.0)
@@ -39,6 +76,13 @@ GEM
39
76
  rack (2.0.6)
40
77
  rack-protection (2.0.4)
41
78
  rack
79
+ rack-test (1.1.0)
80
+ rack (>= 1.0, < 3)
81
+ rails-dom-testing (2.0.3)
82
+ activesupport (>= 4.2.0)
83
+ nokogiri (>= 1.6)
84
+ rails-html-sanitizer (1.0.4)
85
+ loofah (~> 2.2, >= 2.2.2)
42
86
  rainbow (3.0.0)
43
87
  rake (10.5.0)
44
88
  redis (4.0.3)
@@ -82,10 +126,12 @@ PLATFORMS
82
126
  ruby
83
127
 
84
128
  DEPENDENCIES
129
+ actionmailer (> 3.0)
85
130
  activerecord (> 3.0)
86
131
  activesupport (> 3.0)
87
132
  bundler (~> 1.16)
88
133
  bundler-audit
134
+ database_cleaner
89
135
  fakeredis
90
136
  rake (~> 10.0)
91
137
  rspec (~> 3.0)
data/README.md CHANGED
@@ -49,6 +49,8 @@ end
49
49
  # ...
50
50
 
51
51
  User.simple_delay.greeting
52
+ User.simple_delay_for(10.minutes).greeting
53
+ User.simple_delay_until(1.day.from_now).greeting
52
54
  ```
53
55
 
54
56
  To add delay functionality to the instances of a class:
@@ -73,6 +75,31 @@ Three methods are provided that map to the three main invocations for Sidekiq.
73
75
  * `simple_delay_for` -> `perform_in`
74
76
  * `simple_delay_until` -> `perform_at`
75
77
 
78
+ ### Simple Delay Spread
79
+
80
+ Often we want to enqueue a bunch of jobs, but need to spread them out over some period of time to prevent swampping our resources. We use a similar API to [`sidekiq_spread`](https://github.com/Latermedia/sidekiq_spread) to evenly distribute job execution.
81
+
82
+ ```ruby
83
+ class User
84
+ extend SidekiqSimpleDelay::DelayMethods
85
+
86
+ def greeting(name)
87
+ "Hello, #{name}"
88
+ end
89
+ end
90
+
91
+ # ...
92
+
93
+ spread_options = {
94
+ spread_duration: 3.hours,
95
+ spread_in: 15.minutes
96
+ }
97
+
98
+ # Randomly enqueues a job sometime between 15 minutes and 3 hours
99
+ # and 15 minutes from now
100
+ User.simple_delay_spread(spread_options).greeting('Les')
101
+ ```
102
+
76
103
  ### Devops
77
104
 
78
105
  A few conveniences are provided that allow you enable this functionality from the command line.
@@ -120,7 +147,7 @@ One use case of these methods would be for delaying methods on an `ActiveRecord`
120
147
  ```ruby
121
148
  class ApplicationRecord < ActiveRecord::Base
122
149
  def initialize_args
123
- [id]
150
+ [send(self.class.primary_key)]
124
151
  end
125
152
 
126
153
  def self.simple_delay_initialize(*args)
@@ -144,6 +171,33 @@ User.where(column1: true).find_each do |user|
144
171
  end
145
172
  ```
146
173
 
174
+ In fact, this is exactly what `sidekiq_delay` does with its `ActiveRecord` integration. To enable it,
175
+
176
+ ```ruby
177
+ SidekiqSimpleDelay.enable_delay_active_record!
178
+ ```
179
+
180
+ This will try to add the methods to `ApplicationRecord` first if it exists, but falls back to `ActiveRecord::Base` if it doesn't. You can also add it a single class if you want.
181
+
182
+ ```ruby
183
+ SidekiqSimpleDelay.enable_delay_active_record!(User)
184
+ ```
185
+ To spread these jobs out over an interval of time:
186
+ ```ruby
187
+ spread_options = {
188
+ spread_duration: 8.hours,
189
+ spread_at: 3.hours.from_now,
190
+ spread_method: :mod,
191
+ spread_mod_method: :id
192
+ }
193
+
194
+ User.where(column1: true).find_each do |user|
195
+ user.simple_delay_spread(spread_options).long_running_user_task('things')
196
+ end
197
+ ```
198
+
199
+ By modding on the id of the `User` object, we can be sure that if we run this script with the same options, each user job will be executed at about the same relative time. This is useful if you have recurring jobs where having a deterministic offset for a user is beneficial.
200
+
147
201
  ### Simple Objects
148
202
 
149
203
  `SidekiqSimpleDelay` only allows simple objects to be used as parameters to the delayed method. These objects are:
@@ -9,20 +9,90 @@ module SidekiqSimpleDelay
9
9
  # Adds simple_delay class methods to all classes
10
10
  def enable_delay!
11
11
  enable_delay_instance!(Module)
12
+
13
+ return unless defined?(::ActiveSupport)
14
+
15
+ ActiveSupport.on_load(:active_record) do
16
+ SidekiqSimpleDelay.enable_delay_active_record!
17
+ end
18
+
19
+ ActiveSupport.on_load(:action_mailer) do
20
+ SidekiqSimpleDelay.enable_delay_application_mailer!
21
+ end
12
22
  end
13
23
 
14
- # Adds simple_delay class methods to klass
24
+ # Adds simple_delay class methods to a class
25
+ #
26
+ # @param klass [Class] Class to add simple_delay class methods to
15
27
  def enable_delay_class!(klass)
16
28
  raise ArgumentError, 'klass must be a Class' unless klass.class.is_a?(Class)
17
29
 
30
+ return if klass.singleton_class.included_modules.include?(SidekiqSimpleDelay::DelayMethods)
31
+
18
32
  klass.__send__(:extend, SidekiqSimpleDelay::DelayMethods)
19
33
  end
20
34
 
21
- # Adds simple_delay instance methods to klass
35
+ # Adds simple_delay instance methods to class
36
+ #
37
+ # @param klass [Class] Class to add simple_delay instance methods to
22
38
  def enable_delay_instance!(klass)
23
39
  raise ArgumentError, 'klass must be a Class' unless klass.class.is_a?(Class)
24
40
 
41
+ return if klass.included_modules.include?(SidekiqSimpleDelay::DelayMethods)
42
+
25
43
  klass.__send__(:include, SidekiqSimpleDelay::DelayMethods)
26
44
  end
45
+
46
+ # Adds simple_delay functionality to ActiveRecord objects. Attempts to add to {ApplicationRecord} first,
47
+ # the falls back to adding to {ActiveRecord::Base}.
48
+ #
49
+ # @param klass [Class] Class to add simple_delay functionality to. Must inherit from {ActiveRecord::Base}.
50
+ def enable_delay_active_record!(klass = nil)
51
+ klass =
52
+ if !klass.nil?
53
+ klass
54
+ elsif defined?(::ApplicationRecord)
55
+ ::ApplicationRecord
56
+ elsif defined?(::ActiveRecord::Base)
57
+ ::ActiveRecord::Base
58
+ end
59
+
60
+ raise ArgumentError, 'klass must be supplied' if klass.nil?
61
+ raise ArgumentError, 'klass must be a class' unless klass.class.is_a?(Class)
62
+ raise ArgumentError, 'klass must inherit from ActiveRecord::Base' unless klass.ancestors.any? { |c| c.name == 'ActiveRecord::Base' }
63
+
64
+ ar_file = 'sidekiq_simple_delay/extensions/active_record'
65
+ require ar_file unless defined? SidekiqSimpleDelay::ActiveRecord
66
+
67
+ return if klass.included_modules.include?(SidekiqSimpleDelay::ActiveRecord)
68
+
69
+ klass.__send__(:include, SidekiqSimpleDelay::ActiveRecord)
70
+ end
71
+
72
+ # Adds simple_delay functionality to ActionMailer objects. Attempts to add to {ApplicationMailer} first,
73
+ # the falls back to adding to {ActionMailer::Base}.
74
+ #
75
+ # @param klass [Class] Class to add simple_delay functionality to. Must inherit from {ActionMailer::Base}.
76
+ def enable_delay_application_mailer!(klass = nil)
77
+ klass =
78
+ if !klass.nil?
79
+ klass
80
+ elsif defined?(::ApplicationMailer)
81
+ ::ApplicationMailer
82
+ elsif defined?(::ActionMailer::Base)
83
+ ::ActionMailer::Base
84
+ end
85
+
86
+ raise ArgumentError, 'klass must be supplied' if klass.nil?
87
+ raise ArgumentError, 'klass must be a class' unless klass.class.is_a?(Class)
88
+ raise ArgumentError, 'klass must inherit from ActionMailer::Base' unless klass.ancestors.any? { |c| c.name == 'ActionMailer::Base' }
89
+
90
+ ar_file = 'sidekiq_simple_delay/extensions/action_mailer'
91
+ require ar_file unless defined? SidekiqSimpleDelay::ActionMailer
92
+
93
+ return if klass.included_modules.include?(SidekiqSimpleDelay::ActionMailer)
94
+
95
+ klass.__send__(:include, SidekiqSimpleDelay::ActionMailer)
96
+ end
27
97
  end
28
98
  end
@@ -2,24 +2,113 @@
2
2
 
3
3
  require 'sidekiq_simple_delay/delay_worker'
4
4
  require 'sidekiq_simple_delay/generic_proxy'
5
+ require 'sidekiq_simple_delay/utils'
5
6
 
6
7
  module SidekiqSimpleDelay
7
8
  # Aliased class methods to be added to Class
8
9
  module DelayMethods
10
+ # Immediately enqueue a job to handle the delayed action
11
+ #
12
+ # @param options [Hash] options similar to Sidekiq's `perform_async`
9
13
  def simple_sidekiq_delay(options = {})
10
- Proxy.new(SimpleDelayedWorker, self, options)
14
+ Proxy.new(simple_delayed_worker, self, options)
11
15
  end
12
16
 
17
+ # Enqueue a job to handle the delayed action after an elapsed interval
18
+ #
19
+ # @param interval [#to_f] Number of seconds to wait. `to_f` will be called on
20
+ # this argument to convert to seconds.
21
+ # @param options [Hash] options similar to Sidekiq's `perform_in`
13
22
  def simple_sidekiq_delay_for(interval, options = {})
14
- Proxy.new(SimpleDelayedWorker, self, options.merge('at' => Time.now.to_f + interval.to_f))
23
+ Proxy.new(simple_delayed_worker, self, options.merge('at' => Time.now.to_f + interval.to_f))
15
24
  end
16
25
 
26
+ # Enqueue a job to handle the delayed action after at a certain time
27
+ #
28
+ # @param timestamp [#to_f] Timestamp to execute job at. `to_f` will be called on
29
+ # this argument to convert to a timestamp.
30
+ # @param options [Hash] options similar to Sidekiq's `perform_at`
17
31
  def simple_sidekiq_delay_until(timestamp, options = {})
18
- Proxy.new(SimpleDelayedWorker, self, options.merge('at' => timestamp.to_f))
32
+ Proxy.new(simple_delayed_worker, self, options.merge('at' => timestamp.to_f))
33
+ end
34
+
35
+ # Enqueue a job to handle the delayed action in a given timeframe
36
+ #
37
+ # @param timestamp [#to_f] Timestamp to execute job at. `to_f` will be called on
38
+ # this argument to convert to a timestamp.
39
+ # @param options [Hash] options similar to Sidekiq's `perform_at`
40
+ # @option options [Number] :spread_duration Size of window to spread workers out over
41
+ # @option options [Number] :spread_in Start of window offset from now
42
+ # @option options [Number] :spread_at Start of window offset timestamp
43
+ # @option options [rand|mod] :spread_method perform either a random or modulo spread,
44
+ # default: *:rand*
45
+ # @option options [Number] :spread_mod_value value to use for determining mod offset
46
+ # @option options [Symbol] :spread_mod_method method to call to get the value to use
47
+ # for determining mod offset
48
+ def simple_sidekiq_delay_spread(options = {})
49
+ spread_duration = Utils.extract_option(options, :spread_duration, 1.hour).to_f
50
+ spread_in = Utils.extract_option(options, :spread_in, 0).to_f
51
+ spread_at = Utils.extract_option(options, :spread_at)
52
+ spread_method = Utils.extract_option(options, :spread_method, :rand)
53
+ spread_mod_value = Utils.extract_option(options, :spread_mod_value)
54
+ spread_mod_method = Utils.extract_option(options, :spread_mod_method)
55
+
56
+ spread_duration = 0 if spread_duration < 0
57
+ spread_in = 0 if spread_in < 0
58
+
59
+ spread =
60
+ # kick of immediately if the duration is 0
61
+ if spread_duration.zero?
62
+ 0
63
+ else
64
+ case spread_method.to_sym
65
+ when :rand
66
+ Utils.random_number(spread_duration)
67
+ when :mod
68
+ mod_value =
69
+ # The mod value has been supplied
70
+ if !spread_mod_value.nil?
71
+ spread_mod_value
72
+ # Call the supplied method on the target object to get mod value
73
+ elsif !spread_mod_method.nil?
74
+ send(spread_mod_method)
75
+ # Call `spread_mod_method` on target object to get mod value
76
+ elsif respond_to?(:spread_mod_method)
77
+ send(send(:spread_mod_method))
78
+ else
79
+ raise ArgumentError, 'must specify `spread_mod_value` or `spread_mod_method` or taget must respond to `spread_mod_method`'
80
+ end
81
+
82
+ # calculate the mod based offset
83
+ mod_value % spread_duration
84
+ else
85
+ raise ArgumentError, "spread_method must :rand or :mod, `#{spread_method} is invalid`"
86
+ end
87
+ end
88
+
89
+ t =
90
+ if !spread_at.nil?
91
+ # add spread to a timestamp
92
+ spread_at.to_f + spread
93
+ elsif !spread_in.nil?
94
+ # add spread to no plus constant offset
95
+ Time.now.to_f + spread_in.to_f + spread
96
+ else
97
+ # add spread to current time
98
+ Time.now.to_f + spread
99
+ end
100
+
101
+ Proxy.new(SimpleDelayedWorker, self, options.merge('at' => t))
102
+ end
103
+
104
+ # Tell {DelayMethods} which delayed worker to use
105
+ def simple_delayed_worker
106
+ SimpleDelayedWorker
19
107
  end
20
108
 
21
109
  alias simple_delay simple_sidekiq_delay
22
110
  alias simple_delay_for simple_sidekiq_delay_for
23
111
  alias simple_delay_until simple_sidekiq_delay_until
112
+ alias simple_delay_spread simple_sidekiq_delay_spread
24
113
  end
25
114
  end
@@ -1,10 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'sidekiq'
4
- require 'sidekiq_simple_delay/generic_proxy'
5
4
 
6
5
  module SidekiqSimpleDelay
7
- # Worker that handles the delayed functionality
6
+ # Worker that handles the simple_delayed functionality
8
7
  class SimpleDelayedWorker
9
8
  include Sidekiq::Worker
10
9
 
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sidekiq'
4
+
5
+ module SidekiqSimpleDelay
6
+ # Worker that handles the simple_delayed functionality for ActionMailers
7
+ class SimpleDelayedMailer
8
+ include Sidekiq::Worker
9
+
10
+ def perform(args)
11
+ target_klass = Object.const_get(args.fetch('target_klass'))
12
+
13
+ method_name = args['m']
14
+ method_args = args['args']
15
+
16
+ msg = target_klass.__send__(method_name, *method_args)
17
+
18
+ # The email method can return nil, which causes ActionMailer to return
19
+ # an undeliverable empty message.
20
+ raise "#{target.name}##{method_name} returned an undeliverable mail object" unless msg
21
+
22
+ deliver(msg)
23
+ end
24
+
25
+ private
26
+
27
+ def deliver(msg)
28
+ if msg.respond_to?(:deliver_now)
29
+ # Rails 4.2/5.0
30
+ msg.deliver_now
31
+ else
32
+ # Rails 3.2/4.0/4.1
33
+ msg.deliver
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sidekiq_simple_delay/delay_methods'
4
+ require 'sidekiq_simple_delay/delayed_mailer'
5
+
6
+ module SidekiqSimpleDelay
7
+ # Methods to enable simple_delay functionality to work with ActiveRecord
8
+ module ActionMailer
9
+ def self.included(base)
10
+ base.extend(SidekiqSimpleDelay::DelayMethods)
11
+ base.extend(ClassMethods)
12
+ end
13
+
14
+ # Tell {DelayMethods} which delayed worker to use
15
+ module ClassMethods
16
+ def simple_delayed_worker
17
+ SimpleDelayedMailer
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sidekiq_simple_delay/delay_methods'
4
+
5
+ module SidekiqSimpleDelay
6
+ # Methods to enable simple_delay functionality to work with ActiveRecord
7
+ module ActiveRecord
8
+ def self.included(base)
9
+ base.include(SidekiqSimpleDelay::DelayMethods)
10
+ base.extend(SidekiqSimpleDelay::DelayMethods)
11
+ base.extend(ClassMethods)
12
+ end
13
+
14
+ # Args required to fetch this object from the database
15
+ def initialize_args
16
+ [send(self.class.primary_key)]
17
+ end
18
+
19
+ # Class methods to enable simple_delay functionality to work with ActiveRecord
20
+ module ClassMethods
21
+ # Take delay worker args and fetch record from database
22
+ def simple_delay_initialize(*args)
23
+ find(args[0])
24
+ end
25
+ end
26
+ end
27
+ end
@@ -30,6 +30,7 @@ module SidekiqSimpleDelay
30
30
  Set.new([Fixnum, Bignum, Float]).freeze
31
31
  end
32
32
 
33
+ # @private
33
34
  def simple_object?(obj)
34
35
  klass = obj.class
35
36
 
@@ -43,6 +44,27 @@ module SidekiqSimpleDelay
43
44
  false
44
45
  end
45
46
  end
47
+
48
+ # @private
49
+ def extract_option(opts, arg, default = nil)
50
+ [arg.to_sym, arg.to_s].each do |a|
51
+ next unless opts.key?(a)
52
+
53
+ return opts.delete(a)
54
+ end
55
+
56
+ default
57
+ end
58
+
59
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.3.0')
60
+ def random_number(duration)
61
+ SecureRandom.random_number(duration)
62
+ end
63
+ else
64
+ def random_number(duration)
65
+ rand * duration
66
+ end
67
+ end
46
68
  end
47
69
  end
48
70
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SidekiqSimpleDelay
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
data/run_specs CHANGED
@@ -1,4 +1,10 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
- bundle exec rspec spec --tag ~enable_delay:true
4
- bundle exec rspec spec --tag enable_delay:true
3
+ bundle exec rspec spec --tag ~run_tag
4
+ bundle exec rspec spec --tag run_tag:enable_delay
5
+ bundle exec rspec spec --tag run_tag:active_record_base
6
+ bundle exec rspec spec --tag run_tag:application_record
7
+ bundle exec rspec spec --tag run_tag:active_record_single
8
+ bundle exec rspec spec --tag run_tag:action_mailer_base
9
+ bundle exec rspec spec --tag run_tag:application_mailer
10
+ bundle exec rspec spec --tag run_tag:action_mailer_single
@@ -24,10 +24,12 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_dependency('sidekiq')
26
26
 
27
+ spec.add_development_dependency 'actionmailer', '> 3.0'
27
28
  spec.add_development_dependency 'activerecord', '> 3.0'
28
29
  spec.add_development_dependency 'activesupport', '> 3.0'
29
30
  spec.add_development_dependency 'bundler', '~> 1.16'
30
31
  spec.add_development_dependency 'bundler-audit'
32
+ spec.add_development_dependency 'database_cleaner'
31
33
  spec.add_development_dependency 'fakeredis'
32
34
  spec.add_development_dependency 'rake', '~> 10.0'
33
35
  spec.add_development_dependency 'rspec', '~> 3.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq_simple_delay
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Les Fletcher
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-12-01 00:00:00.000000000 Z
11
+ date: 2018-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sidekiq
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: actionmailer
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: activerecord
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +94,20 @@ dependencies:
80
94
  - - ">="
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: database_cleaner
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: fakeredis
85
113
  requirement: !ruby/object:Gem::Requirement
@@ -189,6 +217,7 @@ files:
189
217
  - ".gitignore"
190
218
  - ".rspec"
191
219
  - ".rubocop.yml"
220
+ - CHANGELOG.md
192
221
  - CODE_OF_CONDUCT.md
193
222
  - Gemfile
194
223
  - Gemfile.lock
@@ -200,6 +229,9 @@ files:
200
229
  - lib/sidekiq_simple_delay.rb
201
230
  - lib/sidekiq_simple_delay/delay_methods.rb
202
231
  - lib/sidekiq_simple_delay/delay_worker.rb
232
+ - lib/sidekiq_simple_delay/delayed_mailer.rb
233
+ - lib/sidekiq_simple_delay/extensions/action_mailer.rb
234
+ - lib/sidekiq_simple_delay/extensions/active_record.rb
203
235
  - lib/sidekiq_simple_delay/generic_proxy.rb
204
236
  - lib/sidekiq_simple_delay/utils.rb
205
237
  - lib/sidekiq_simple_delay/version.rb