delayed_cron 0.2.6 → 0.2.7

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
  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