sidekiq_schedulable 0.0.1 → 0.0.2

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