sidekiq_schedulable 0.0.1 → 0.0.2

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: 558a8b58ecf33d2edc81636f2f5ba511100a6378
4
- data.tar.gz: 8a4596c211c0f8c14a4dfbe2afe14f1a26c312c9
3
+ metadata.gz: 1064f6cde72a8cf64dc6d6b8ca33772fd07e82b2
4
+ data.tar.gz: 353880a557b65213b9638853962aa5cca164f59a
5
5
  SHA512:
6
- metadata.gz: 8b0da8f414f5fc013f18dd7f4d1c321662f883c3e5e94ccd780f7b280430b86ae76c9f34793508b3e951a7bc3dc2b943e4abeeabe141a7066edda7c31f72c18d
7
- data.tar.gz: 2a7ffab36ba92166caffe4e197b86784e4d327a2b484e3d30ee00325ff4bb24e873f7ce868490e36911e1b9d36378bd88995e154bb7a62823ee657a425657b5e
6
+ metadata.gz: 9cef8200ad866b2e733ca179af8055ae3d3813c29c54c3d62431af7eccd6da041bdc1bc5a9069f0029dafd230c74b9eae98c21e2c3b67ff1a5ef78a78433a401
7
+ data.tar.gz: e7c691de4d29031ffa8c210fb6d05b4a61716c3832b32bbfbb9b1f1c0f76729270de2ab266e5619fcc2dd85632f673ff4e27e60ee1e756ff46d07ee2d81f4d51
@@ -5,10 +5,11 @@ module Sidekiq
5
5
  end
6
6
 
7
7
  module ClassMethods
8
- def sidekiq_schedule(schedule)
8
+ def sidekiq_schedule(schedule, options = {})
9
9
  SidekiqSchedulable.schedules[self.to_s] = {
10
10
  worker: self,
11
- at: schedule
11
+ at: schedule,
12
+ options: options
12
13
  }
13
14
  end
14
15
  end
@@ -12,7 +12,7 @@ module SidekiqSchedulable
12
12
  def self.boot!
13
13
  Sidekiq.configure_server do |config|
14
14
  config.server_middleware do |chain|
15
- chain.add Middleware::Server
15
+ chain.add Middleware::Server, schedules
16
16
  end
17
17
 
18
18
  config.client_middleware do |chain|
@@ -7,7 +7,7 @@ module SidekiqSchedulable
7
7
 
8
8
  def call(worker_class, item, queue, redis_pool)
9
9
  if schedule = @schedules[worker_class]
10
- item['schedule'] = schedule[:at]
10
+ item['scheduled'] = true
11
11
  end
12
12
  yield
13
13
  end
@@ -3,18 +3,24 @@ require 'sidekiq_schedulable/schedule'
3
3
  module SidekiqSchedulable
4
4
  module Middleware
5
5
  class Server
6
+ def initialize(schedules = {})
7
+ @schedules = schedules
8
+ end
9
+
6
10
  def call(worker, item, queue)
11
+ start_time = Time.now
7
12
  yield
8
13
  ensure
9
- schedule_next_job(worker, item) if item['schedule']
14
+ schedule_next_job(item, start_time) if item['scheduled']
10
15
  end
11
16
 
12
17
  private
13
18
 
14
- def schedule_next_job(worker, item)
15
- schedule = item['schedule']
16
- time = Schedule.next_time(schedule)
17
- worker.class.perform_at(time)
19
+ def schedule_next_job(item, start_time)
20
+ class_name = item['class']
21
+ if schedule = @schedules[class_name]
22
+ Schedule.enqueue(schedule, start_time)
23
+ end
18
24
  end
19
25
  end
20
26
  end
@@ -2,8 +2,23 @@ require 'parse-cron'
2
2
 
3
3
  module SidekiqSchedulable
4
4
  module Schedule
5
+ def self.enqueue(schedule, last_run = nil)
6
+ worker = schedule[:worker]
7
+ time = next_time(schedule[:at])
8
+ if schedule[:options][:last_run]
9
+ last_time = last_run || last_time(schedule[:at])
10
+ worker.perform_at(time, last_time.to_f)
11
+ else
12
+ worker.perform_at(time)
13
+ end
14
+ end
15
+
5
16
  def self.next_time(schedule)
6
17
  CronParser.new(schedule).next(Time.now)
7
18
  end
19
+
20
+ def self.last_time(schedule)
21
+ CronParser.new(schedule).last(Time.now)
22
+ end
8
23
  end
9
24
  end
@@ -12,11 +12,9 @@ module SidekiqSchedulable
12
12
  end
13
13
 
14
14
  def schedule!
15
- schedules.each do |worker_class, schedule|
16
- unless already_scheduled?(worker_class)
17
- time = Schedule.next_time(schedule[:at])
18
- worker = schedule[:worker]
19
- worker.perform_at(time)
15
+ schedules.each do |klass_name, schedule|
16
+ unless already_scheduled?(klass_name)
17
+ Schedule.enqueue(schedule)
20
18
  end
21
19
  end
22
20
  end
@@ -25,15 +23,15 @@ module SidekiqSchedulable
25
23
 
26
24
  attr_reader :schedules, :current_jobs
27
25
 
28
- def already_scheduled?(worker_class)
26
+ def already_scheduled?(klass_name)
29
27
  scheduled_jobs.any? do |job|
30
- job.item['class'] == worker_class
28
+ job.item['class'] == klass_name
31
29
  end
32
30
  end
33
31
 
34
32
  def scheduled_jobs
35
33
  @scheduled_jobs ||= current_jobs.select do |job|
36
- job.item['schedule']
34
+ job.item['scheduled']
37
35
  end
38
36
  end
39
37
  end
@@ -1,3 +1,3 @@
1
1
  module SidekiqSchedulable
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end
@@ -12,34 +12,65 @@ describe SidekiqSchedulable do
12
12
  include Sidekiq::Schedulable
13
13
 
14
14
  sidekiq_schedule '*/10 * * * * *'
15
+
16
+ def perform
17
+ :done
18
+ end
19
+ end
20
+
21
+ class AnotherWorker
22
+ include Sidekiq::Worker
23
+ include Sidekiq::Schedulable
24
+
25
+ sidekiq_schedule '0 12 * * * *', last_run: true
26
+
27
+ def perform(last_run)
28
+ Time.now - Time.at(last_run)
29
+ end
15
30
  end
16
31
 
17
32
  let(:midnight) { Time.new(2015, 10, 1, 0, 0, 0) }
18
33
  let(:next_ten_minutes) { midnight + 10 * 60 }
19
34
 
35
+ let(:schedules) {
36
+ {
37
+ 'TestWorker' => {
38
+ worker: TestWorker,
39
+ at: '*/10 * * * * *',
40
+ options: {}
41
+ },
42
+ 'AnotherWorker' => {
43
+ worker: AnotherWorker,
44
+ at: '0 12 * * * *',
45
+ options: { last_run: true }
46
+ }
47
+ }
48
+ }
49
+
20
50
  before do
21
51
  Timecop.freeze(midnight)
22
52
  end
23
53
 
24
54
  after do
25
- TestWorker.jobs.clear
55
+ Sidekiq::Worker.clear_all
26
56
  end
27
57
 
28
58
  it "adds the schedule to the schedules" do
29
- schedule = SidekiqSchedulable.schedules["TestWorker"]
59
+ schedule = SidekiqSchedulable.schedules['TestWorker']
30
60
 
31
61
  expect(schedule[:at]).to eq('*/10 * * * * *')
32
62
  expect(schedule[:worker]).to eq(TestWorker)
63
+ expect(schedule[:options]).to eq({})
33
64
  end
34
65
 
35
66
  describe SidekiqSchedulable::Middleware::Server do
36
67
  let(:worker) { TestWorker.new }
37
- let(:middleware) { SidekiqSchedulable::Middleware::Server.new }
68
+ let(:middleware) { SidekiqSchedulable::Middleware::Server.new(schedules) }
38
69
 
39
70
  it "ensures the job is re-enqueued for next time" do
40
71
  expect {
41
- middleware.call(worker, { 'schedule' => '*/10 * * * * *' }, 'a queue') do
42
- raise "Error"
72
+ middleware.call(worker, { 'scheduled' => true, 'class' => 'TestWorker' }, 'a_queue') do
73
+ raise 'Error'
43
74
  end
44
75
  }.to raise_error RuntimeError, "Error"
45
76
 
@@ -50,17 +81,23 @@ describe SidekiqSchedulable do
50
81
  end
51
82
 
52
83
  it "does not re-schedule if the job has no schedule" do
53
- middleware.call(worker, {}, 'a queue') do
84
+ middleware.call(worker, {}, 'a_queue') do
54
85
  true
55
86
  end
56
87
 
57
88
  expect(TestWorker.jobs.size).to eq(0)
58
89
  end
59
- end
60
90
 
61
- let(:schedules) {
62
- { "TestWorker" => { worker: TestWorker, at: '*/10 * * * * *' } }
63
- }
91
+ it "adds the last_run argument based on the last job start time" do
92
+ middleware.call(worker, { 'scheduled' => true, 'class' => 'AnotherWorker' }, 'a_queue') do
93
+ true
94
+ end
95
+
96
+ expect(AnotherWorker.jobs.size).to eq(1)
97
+ expect(AnotherWorker.jobs.first['args']).to eq([Time.now.to_f])
98
+ expect { AnotherWorker.drain }.to_not raise_error
99
+ end
100
+ end
64
101
 
65
102
  describe SidekiqSchedulable::Middleware::Client do
66
103
  let(:middleware) { SidekiqSchedulable::Middleware::Client.new(schedules) }
@@ -68,17 +105,17 @@ describe SidekiqSchedulable do
68
105
  it "adds the schedule to the job item" do
69
106
  item = {}
70
107
 
71
- middleware.call("TestWorker", item, "a queue", nil) do
108
+ middleware.call('TestWorker', item, 'a queue', nil) do
72
109
  true
73
110
  end
74
111
 
75
- expect(item['schedule']).to eq('*/10 * * * * *')
112
+ expect(item['scheduled']).to eq(true)
76
113
  end
77
114
 
78
115
  it "does not add the schedule if the worker has no schedule" do
79
116
  item = {}
80
117
 
81
- middleware.call("Array", item, "a queue", nil) do
118
+ middleware.call('Array', item, 'a_queue', nil) do
82
119
  true
83
120
  end
84
121
 
@@ -100,6 +137,16 @@ describe SidekiqSchedulable do
100
137
  expect(TestWorker.jobs.first['at']).to eq(next_ten_minutes.to_f)
101
138
  end
102
139
 
140
+ it "adds the last_run argument based on the schedule" do
141
+ last_run = midnight - 60 * 60 * 12
142
+
143
+ SidekiqSchedulable::Startup.schedule!(schedules, current_jobs)
144
+
145
+ expect(AnotherWorker.jobs.size).to eq(1)
146
+ expect(AnotherWorker.jobs.first['args']).to eq([last_run.to_f])
147
+ expect { AnotherWorker.drain }.to_not raise_error
148
+ end
149
+
103
150
  it "does not enqueue a duplicate job for the given worker" do
104
151
  SidekiqSchedulable::Startup.schedule!(schedules, current_jobs)
105
152
  SidekiqSchedulable::Startup.schedule!(schedules, current_jobs)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq_schedulable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Buchanan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-12 00:00:00.000000000 Z
11
+ date: 2015-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sidekiq