delayed_cron 0.2.6 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: af92ec64204d2a7f01c4dbb31c511603e87b43f0
4
- data.tar.gz: ec7ea779e56c8f82e2112eb19799beac0f1327e7
3
+ metadata.gz: 1793dcbe15524332e26770ae9e5951961a3730d4
4
+ data.tar.gz: 6886b240e7ccf4f709782367348bde6239d2b515
5
5
  SHA512:
6
- metadata.gz: 827a3222ad6c991c8a6ffb542ce3376efce3f43a922bf2fc8560b6de8f65db923d354b50c456716860bb1029aab773adb48c68ee2fd73979241c56aaca867631
7
- data.tar.gz: 6f5a6750da95164b5531e4f5e4d9570888099a4482a8e3a1b7f1b2e2d25a87f68ea80d000fa56e80ef400a90c8302a7b6b264769024dfc79ac75a20873f6c6e9
6
+ metadata.gz: 6dcef7ec119d6b38aa6ed8aecd10c78bd85c667853e85e0575399cf4abfcdca8259c8cf7338f37ee9b88c245bea3e7beb114c854490e5a4050afcc535c9cb0ec
7
+ data.tar.gz: 339aa0bca689fe888371edef9567c92199622258d25b378032eaac3573973626acd6697df05a78d931b4974579f2344ff0ad1912c94a4cf814b2be90ed50f954
data/.gitignore CHANGED
@@ -1,3 +1,3 @@
1
1
  *.DS_Store
2
2
  pkg
3
- Gemfile.lock
3
+ Gemfile.lock
data/delayed_cron.gemspec CHANGED
@@ -20,6 +20,8 @@ Gem::Specification.new do |s|
20
20
  s.add_development_dependency "timecop"
21
21
  s.add_development_dependency "rspec-sidekiq"
22
22
  s.add_development_dependency "codeclimate-test-reporter"
23
+ s.add_development_dependency "hashie"
24
+ s.add_development_dependency "debugger"
23
25
 
24
26
  s.files = `git ls-files`.split("\n")
25
27
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -8,38 +8,48 @@ module DelayedCron
8
8
  sidekiq_options :queue => :cron_job
9
9
 
10
10
  def self.enqueue_delayed_cron(klass, method_name, options)
11
- unless do_not_enqueue?(klass, method_name)
12
- options.symbolize_keys!
11
+ options.symbolize_keys!
12
+ unless do_not_enqueue?(klass, method_name, options)
13
13
  perform_in(options[:interval], klass, method_name, options)
14
14
  end
15
15
  end
16
16
 
17
- def self.do_not_enqueue?(klass, method_name)
18
- scheduled?(klass, method_name) ||
19
- enqueued?(klass, method_name) ||
20
- retrying?(klass, method_name)
17
+ def self.do_not_enqueue?(klass, method_name, options)
18
+ scheduled?(klass, method_name, options) ||
19
+ enqueued?(klass, method_name, options) ||
20
+ retrying?(klass, method_name, options)
21
21
  end
22
22
 
23
- def self.retrying?(klass, method_name)
23
+ def self.retrying?(klass, method_name, options)
24
24
  ::Sidekiq::RetrySet.new.collect(&:item).select do |item|
25
- matches_kass_and_method?(item, klass, method_name)
25
+ matches?(item, klass, method_name, options)
26
26
  end.present?
27
27
  end
28
28
 
29
- def self.scheduled?(klass, method_name)
29
+ def self.scheduled?(klass, method_name, options)
30
30
  ::Sidekiq::ScheduledSet.new.collect(&:item).select do |item|
31
- matches_kass_and_method?(item, klass, method_name)
31
+ matches?(item, klass, method_name, options)
32
32
  end.present?
33
33
  end
34
34
 
35
- def self.enqueued?(klass, method_name)
35
+ def self.enqueued?(klass, method_name, options)
36
36
  ::Sidekiq::Queue.new("cron_job").collect(&:item).select do |item|
37
- matches_kass_and_method?(item, klass, method_name)
37
+ matches?(item, klass, method_name, options)
38
38
  end.present?
39
39
  end
40
40
 
41
- def self.matches_kass_and_method?(item, klass, method_name)
42
- item["args"][0] == klass && item["args"][1] == method_name.to_s
41
+ def self.matches?(item, klass, method_name, options)
42
+ class_and_method_match?(item["args"], klass, method_name) &&
43
+ at_match?(item["args"][2], options)
44
+ end
45
+
46
+ def self.at_match?(arg_options, options)
47
+ return true unless !!arg_options["at"] && !!options[:at]
48
+ arg_options["at"] == options[:at]
49
+ end
50
+
51
+ def self.class_and_method_match?(args, klass, method_name)
52
+ args[0] == klass && args[1] == method_name.to_s
43
53
  end
44
54
 
45
55
  def perform(klass, method_name, options)
@@ -0,0 +1,72 @@
1
+ module DelayedCron
2
+ module Scheduling
3
+
4
+ def schedule(klass, method_name, options)
5
+ parsed_options = parse_options(options)
6
+ if parsed_options.is_a?(Array)
7
+ parsed_options.each do |opts|
8
+ processor.enqueue_delayed_cron(klass, method_name, opts)
9
+ end
10
+ else
11
+ processor.enqueue_delayed_cron(klass, method_name, parsed_options)
12
+ end
13
+ end
14
+
15
+ def parse_options(options)
16
+ original_options = options
17
+ if at = options[:at]
18
+ options = if at.is_a?(Array)
19
+ at.map do |at_option|
20
+ add_interval(original_options.merge(at: at_option))
21
+ end
22
+ else
23
+ add_interval(options)
24
+ end
25
+ end
26
+ options
27
+ end
28
+
29
+ def add_interval(options)
30
+ date = beginning_of_day(options[:interval].to_i)
31
+ options[:interval] = adjust_interval(date, options[:at])
32
+ options
33
+ end
34
+
35
+ def timing_opts(interval, options_at)
36
+ timing_opts = { interval: interval }
37
+ timing_opts.merge!(at: options_at) if options_at.present?
38
+ timing_opts
39
+ end
40
+
41
+ def beginning_of_day(seconds)
42
+ (Time.now + seconds).beginning_of_day
43
+ end
44
+
45
+ def adjust_interval(date, time_string)
46
+ adjusted_date(date, time_string).to_i - Time.now.to_i
47
+ end
48
+
49
+ def adjusted_date(date, time_string)
50
+ time = parse_time(time_string.split(/:|\ /).map(&:to_i))
51
+ DateTime.civil(
52
+ date.year,
53
+ date.month,
54
+ date.day,
55
+ time[:hours],
56
+ time[:mins],
57
+ time[:secs],
58
+ Rational(time[:tz], 2400)
59
+ )
60
+ end
61
+
62
+ def parse_time(time_array)
63
+ {
64
+ hours: time_array[0],
65
+ mins: time_array[1],
66
+ secs: time_array[2] || 0,
67
+ tz: time_array[3] || Time.now.strftime("%z").to_i
68
+ }
69
+ end
70
+
71
+ end
72
+ end
@@ -1,3 +1,3 @@
1
1
  module DelayedCron
2
- VERSION = "0.2.6"
2
+ VERSION = "0.2.7"
3
3
  end
data/lib/delayed_cron.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'delayed_cron/jobs'
2
+ require 'delayed_cron/scheduling'
2
3
  require 'delayed_cron/railtie'
3
4
 
4
5
  module DelayedCron
@@ -7,6 +8,8 @@ module DelayedCron
7
8
 
8
9
  class << self
9
10
 
11
+ include DelayedCron::Scheduling
12
+
10
13
  def setup
11
14
  yield self
12
15
  define_cron_jobs
@@ -34,47 +37,12 @@ module DelayedCron
34
37
  return DelayedCron::Jobs::SuckerPunch if defined? ::SuckerPunch
35
38
  end
36
39
 
37
- def schedule(klass, method_name, options)
38
- if options[:at]
39
- options[:interval] = adjust_interval(beginning_of_day(options[:interval].to_i), options[:at])
40
- end
41
- processor.enqueue_delayed_cron(klass, method_name, options)
42
- end
43
-
44
- def timing_opts(interval, options_at)
45
- timing_opts = { interval: interval }
46
- timing_opts.merge!(at: options_at) if options_at.present?
47
- timing_opts
48
- end
49
-
50
40
  def process_job(klass, method_name, options)
51
41
  # TODO: add ability to send args to klass method
52
42
  klass.constantize.send(method_name)
53
43
  schedule(klass, method_name, options)
54
44
  end
55
45
 
56
- def beginning_of_day(seconds)
57
- (Time.now + seconds).beginning_of_day
58
- end
59
-
60
- def adjust_interval(date, time_string)
61
- adjusted_date(date, time_string).to_i - Time.now.to_i
62
- end
63
-
64
- def adjusted_date(date, time_string)
65
- time = parse_time(time_string.split(/:|\ /).map(&:to_i))
66
- DateTime.civil(date.year, date.month, date.day, time[:hours], time[:mins], time[:secs], Rational(time[:tz], 2400))
67
- end
68
-
69
- def parse_time(time_array)
70
- {
71
- hours: time_array[0],
72
- mins: time_array[1],
73
- secs: time_array[2] || 0,
74
- tz: time_array[3] || Time.now.strftime("%z").to_i
75
- }
76
- end
77
-
78
46
  end
79
47
 
80
48
  module Glue
@@ -61,28 +61,6 @@ describe DelayedCron do
61
61
 
62
62
  end
63
63
 
64
- describe ".schedule" do
65
- it "schedules cron jobs" do
66
- DelayedCron.schedule("SomeClass", "long_method", { interval: 1.hour })
67
- expect(DelayedCron.processor).to be_processed_in :cron_job
68
- expect(DelayedCron.processor.jobs.size).to eq(1)
69
- end
70
- end
71
-
72
- describe ".timing_opts" do
73
-
74
- let(:options) do
75
- { interval: 1.day, at: "05:00:00 -0400" }
76
- end
77
-
78
- it "collects the timing options" do
79
- interval = { interval: 1.day }
80
- timing_opts = DelayedCron.timing_opts(options[:interval], options[:at])
81
- expect(timing_opts).to eq(options)
82
- expect(timing_opts).not_to eq(interval)
83
- end
84
- end
85
-
86
64
  describe ".process_job" do
87
65
 
88
66
  it "should call the cron jobs method" do
@@ -100,27 +78,6 @@ describe DelayedCron do
100
78
 
101
79
  end
102
80
 
103
- describe ".beginning_of_day" do
104
- it "returns the beginning of the day for the interval" do
105
- seconds = 2.days.to_i
106
- beginning_of_day_2_days_from_now = DelayedCron.beginning_of_day(seconds)
107
- expect(beginning_of_day_2_days_from_now).to be < 2.days.from_now
108
- expect(beginning_of_day_2_days_from_now).to be > 1.day.from_now
109
- end
110
- end
111
-
112
- describe ".adjust_interval" do
113
- it "adjusts the interval based on the :at option" do
114
- # Set Time.now to January 1, 2014 12:00:00 PM
115
- Timecop.freeze(Time.local(2014, 1, 1, 12, 0, 0))
116
- interval = 9.days
117
- adjusted_interval = interval - 12.hours
118
- DelayedCron.processor.should_receive(:enqueue_delayed_cron)
119
- .with("SomeClass", "long_method", { interval: adjusted_interval.to_i, at: "00:00" })
120
- DelayedCron.schedule("SomeClass", "long_method", { interval: interval, at: "00:00" })
121
- end
122
- end
123
-
124
81
  describe "cron_job" do
125
82
  context 'if not present' do
126
83
  it "schedules cron jobs found in a model" do
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+ require 'timecop'
3
+ require 'rspec-sidekiq'
4
+ require 'hashie'
5
+
6
+ describe DelayedCron::Jobs::Sidekiq do
7
+ let(:options) { { interval: 123, at: "00:00:00 -0500" } }
8
+ let(:options_1) { { interval: 123, at: "11:00:00 -0500" } }
9
+ let(:item_hash) { { "args" => ["SomeClass", "some_method", options] } }
10
+ let(:item) { Hashie::Mash.new(item: item_hash) }
11
+ let(:item_response) { [item] }
12
+ let(:sidekiq) { DelayedCron::Jobs::Sidekiq }
13
+
14
+ before do
15
+ allow(Sidekiq::RetrySet).to receive(:new).and_return(item_response)
16
+ allow(Sidekiq::ScheduledSet).to receive(:new).and_return(item_response)
17
+ allow(Sidekiq::Queue).to receive(:new).with("cron_job").and_return(item_response)
18
+ end
19
+
20
+ describe ".enqueue_delayed_cron" do
21
+ end
22
+
23
+ describe ".do_not_enqueue?" do
24
+ end
25
+
26
+ describe ".retrying?" do
27
+ it "returns true if a job is retrying" do
28
+ retrying = sidekiq.retrying?("SomeClass", "some_method", options)
29
+ expect(retrying).to eq(true)
30
+ end
31
+
32
+ it "returns false if a job is not retrying" do
33
+ not_retrying = sidekiq.retrying?("NotClass", "some_method", options)
34
+ expect(not_retrying).to eq(false)
35
+ end
36
+
37
+ it "returns false if a job is retrying, but for a different time" do
38
+ not_retrying = sidekiq.retrying?("SomeClass", "some_method", options_1)
39
+ expect(not_retrying).to eq(false)
40
+ end
41
+ end
42
+
43
+ describe ".scheduled?" do
44
+ it "returns true if a job is scheduled" do
45
+ scheduled = sidekiq.scheduled?("SomeClass", "some_method", options)
46
+ expect(scheduled).to eq(true)
47
+ end
48
+
49
+ it "returns false if a job is not scheduled" do
50
+ not_scheduled = sidekiq.scheduled?("NotClass", "some_method", options)
51
+ expect(not_scheduled).to eq(false)
52
+ end
53
+
54
+ it "returns false if a job is scheduled, but for a different time" do
55
+ not_scheduled = sidekiq.scheduled?("SomeClass", "some_method", options_1)
56
+ expect(not_scheduled).to eq(false)
57
+ end
58
+ end
59
+
60
+ describe ".enqueued?" do
61
+ it "returns true if a job is already enqueued" do
62
+ enqueued = sidekiq.enqueued?("SomeClass", "some_method", options)
63
+ expect(enqueued).to eq(true)
64
+ end
65
+
66
+ it "returns false if a job is not enqueued" do
67
+ not_enqueued = sidekiq.enqueued?("NotClass", "some_method", options)
68
+ expect(not_enqueued).to eq(false)
69
+ end
70
+
71
+ it "returns false if a job is enqueued, but for a different time" do
72
+ not_enqueued = sidekiq.enqueued?("SomeClass", "some_method", options_1)
73
+ expect(not_enqueued).to eq(false)
74
+ end
75
+ end
76
+
77
+ describe ".matches?" do
78
+ end
79
+
80
+ describe ".at_match?" do
81
+ end
82
+
83
+ describe ".class_and_method_match?" do
84
+ end
85
+
86
+ describe "#perform" do
87
+ end
88
+
89
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+ require 'timecop'
3
+ require 'rspec-sidekiq'
4
+
5
+ describe DelayedCron::Scheduling do
6
+
7
+ describe ".schedule" do
8
+ it "schedules cron jobs" do
9
+ DelayedCron.schedule("SomeClass", "long_method", { interval: 1.hour })
10
+ expect(DelayedCron.processor).to be_processed_in :cron_job
11
+ expect(DelayedCron.processor.jobs.size).to eq(1)
12
+ end
13
+ end
14
+
15
+ describe ".parse_options" do
16
+ let(:at_string) { { interval: 1.day, at: "00:00:00 -0500" } }
17
+ let(:at_array) { { interval: 1.day, at: ["00:00:00 -0500", "01:00:00 -0500"]} }
18
+ let(:no_at) { { interval: 1.day } }
19
+
20
+ it "parses options `at` option as string" do
21
+ expect(DelayedCron.parse_options(at_string)[:at]).to eq("00:00:00 -0500")
22
+ end
23
+
24
+ it "parses options `at` option as array" do
25
+ expected_options_array = [
26
+ { interval: 123, at: "00:00:00 -0500" },
27
+ { interval: 123, at: "01:00:00 -0500" }
28
+ ]
29
+ expect(DelayedCron.parse_options(at_array)[0][:at]).to eq("00:00:00 -0500")
30
+ expect(DelayedCron.parse_options(at_array)[1][:at]).to eq("01:00:00 -0500")
31
+ end
32
+
33
+ it "does not change options if `at` is not present" do
34
+ expect(DelayedCron.parse_options(no_at)).to eq(no_at)
35
+ end
36
+ end
37
+
38
+ describe ".timing_opts" do
39
+
40
+ let(:options) do
41
+ { interval: 1.day, at: "05:00:00 -0400" }
42
+ end
43
+
44
+ it "collects the timing options" do
45
+ interval = { interval: 1.day }
46
+ timing_opts = DelayedCron.timing_opts(options[:interval], options[:at])
47
+ expect(timing_opts).to eq(options)
48
+ expect(timing_opts).not_to eq(interval)
49
+ end
50
+ end
51
+
52
+ describe ".beginning_of_day" do
53
+ it "returns the beginning of the day for the interval" do
54
+ seconds = 2.days.to_i
55
+ beginning_of_day_2_days_from_now = DelayedCron.beginning_of_day(seconds)
56
+ expect(beginning_of_day_2_days_from_now).to be < 2.days.from_now
57
+ expect(beginning_of_day_2_days_from_now).to be > 1.day.from_now
58
+ end
59
+ end
60
+
61
+ describe ".adjust_interval" do
62
+ it "adjusts the interval based on the :at option" do
63
+ # Set Time.now to January 1, 2014 12:00:00 PM
64
+ Timecop.freeze(Time.local(2014, 1, 1, 12, 0, 0))
65
+ interval = 9.days
66
+ adjusted_interval = interval - 12.hours
67
+ DelayedCron.processor.should_receive(:enqueue_delayed_cron)
68
+ .with("SomeClass", "long_method", { interval: adjusted_interval.to_i, at: "00:00" })
69
+ DelayedCron.schedule("SomeClass", "long_method", { interval: interval, at: "00:00" })
70
+ end
71
+ end
72
+
73
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: delayed_cron
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Grubbs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-30 00:00:00.000000000 Z
11
+ date: 2016-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: delayed_job
@@ -136,6 +136,34 @@ dependencies:
136
136
  - - '>='
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: hashie
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: debugger
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - '>='
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - '>='
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
139
167
  description: Run your cron jobs with sidekiq, delayed_job, resque, or sucker_punch.
140
168
  email: justin@sellect.com
141
169
  executables: []
@@ -158,9 +186,12 @@ files:
158
186
  - lib/delayed_cron/jobs/sidekiq.rb
159
187
  - lib/delayed_cron/jobs/sucker_punch.rb
160
188
  - lib/delayed_cron/railtie.rb
189
+ - lib/delayed_cron/scheduling.rb
161
190
  - lib/delayed_cron/version.rb
162
191
  - rails/init.rb
163
192
  - spec/delayed_cron_spec.rb
193
+ - spec/jobs/sidekiq_spec.rb
194
+ - spec/scheduling_spec.rb
164
195
  - spec/spec_helper.rb
165
196
  homepage: http://github.com/sellect/delayed_cron
166
197
  licenses: []
@@ -181,10 +212,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
212
  version: '0'
182
213
  requirements: []
183
214
  rubyforge_project:
184
- rubygems_version: 2.0.6
215
+ rubygems_version: 2.4.8
185
216
  signing_key:
186
217
  specification_version: 4
187
218
  summary: Run your cron jobs with sidekiq, delayed_job, resque, or sucker_punch.
188
219
  test_files:
189
220
  - spec/delayed_cron_spec.rb
221
+ - spec/jobs/sidekiq_spec.rb
222
+ - spec/scheduling_spec.rb
190
223
  - spec/spec_helper.rb