sidetiq 0.1.5 → 0.2.0
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.
- data/.travis.yml +10 -2
- data/CHANGELOG.md +12 -0
- data/lib/sidetiq/clock.rb +26 -13
- data/lib/sidetiq/middleware.rb +4 -1
- data/lib/sidetiq/schedulable.rb +16 -1
- data/lib/sidetiq/version.rb +2 -2
- data/sidetiq.gemspec +3 -3
- data/test/helper.rb +4 -2
- data/test/test_clock.rb +71 -2
- data/test/test_worker.rb +25 -0
- metadata +10 -8
data/.travis.yml
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
language: ruby
|
2
|
+
before_script:
|
3
|
+
- bundle exec rake compile
|
2
4
|
rvm:
|
5
|
+
- 1.9.2
|
3
6
|
- 1.9.3
|
4
7
|
- 2.0.0
|
5
|
-
|
6
|
-
-
|
8
|
+
- ruby-head
|
9
|
+
- jruby-19mode
|
10
|
+
- rbx-19mode
|
11
|
+
matrix:
|
12
|
+
allow_failures:
|
13
|
+
- rvm: 1.9.2
|
14
|
+
- rvm: jruby-19mode
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
0.2.0
|
2
|
+
-----
|
3
|
+
|
4
|
+
- Add class methods to get last and next scheduled occurrence.
|
5
|
+
- Pass last and next (current) occurrence to #perform, if desired.
|
6
|
+
This checks the method arity of #perform.
|
7
|
+
- Bump Sidekiq dependency to 2.8.0
|
8
|
+
- Fix incorrectly assigned Thread priority.
|
9
|
+
- Adjust clock sleep depending of execution time of the last tick.
|
10
|
+
- Don't log thread object ids.
|
11
|
+
- Issue a warning from the middleware if the clock thread died previously.
|
12
|
+
|
1
13
|
0.1.5
|
2
14
|
-----
|
3
15
|
|
data/lib/sidetiq/clock.rb
CHANGED
@@ -92,7 +92,7 @@ module Sidetiq
|
|
92
92
|
Sidekiq.logger.info "Sidetiq::Clock start"
|
93
93
|
@thread = Thread.start { clock { tick } }
|
94
94
|
@thread.abort_on_exception = true
|
95
|
-
@thread.priority = Sidetiq.config.
|
95
|
+
@thread.priority = Sidetiq.config.priority
|
96
96
|
@thread
|
97
97
|
end
|
98
98
|
|
@@ -131,15 +131,20 @@ module Sidetiq
|
|
131
131
|
|
132
132
|
def enqueue(worker, time)
|
133
133
|
key = "sidetiq:#{worker.name}"
|
134
|
+
time_f = time.to_f
|
134
135
|
|
135
136
|
synchronize_clockworks("#{key}:lock") do |redis|
|
136
|
-
|
137
|
+
next_run = (redis.get("#{key}:next") || -1).to_f
|
137
138
|
|
138
|
-
if
|
139
|
-
time_f
|
140
|
-
|
141
|
-
redis.
|
142
|
-
|
139
|
+
if next_run < time_f
|
140
|
+
Sidekiq.logger.info "Sidetiq::Clock enqueue #{worker.name} (at: #{time_f}) (last: #{next_run})"
|
141
|
+
|
142
|
+
redis.mset("#{key}:last", next_run, "#{key}:next", time_f)
|
143
|
+
|
144
|
+
arity = [worker.instance_method(:perform).arity - 1, -1].max
|
145
|
+
args = [next_run, time_f][0..arity]
|
146
|
+
|
147
|
+
worker.perform_at(time, *args)
|
143
148
|
end
|
144
149
|
end
|
145
150
|
end
|
@@ -147,24 +152,32 @@ module Sidetiq
|
|
147
152
|
def synchronize_clockworks(lock)
|
148
153
|
Sidekiq.redis do |redis|
|
149
154
|
if redis.setnx(lock, 1)
|
150
|
-
Sidekiq.logger.debug "Sidetiq::Clock lock #{lock}
|
155
|
+
Sidekiq.logger.debug "Sidetiq::Clock lock #{lock}"
|
151
156
|
|
152
157
|
redis.pexpire(lock, Sidetiq.config.lock_expire)
|
153
158
|
yield redis
|
154
159
|
redis.del(lock)
|
155
160
|
|
156
|
-
Sidekiq.logger.debug "Sidetiq::Clock unlock #{lock}
|
161
|
+
Sidekiq.logger.debug "Sidetiq::Clock unlock #{lock}"
|
157
162
|
end
|
158
163
|
end
|
159
164
|
end
|
160
165
|
|
161
166
|
def clock
|
162
167
|
loop do
|
163
|
-
yield
|
164
|
-
|
165
|
-
|
168
|
+
sleep_time = time { yield }
|
169
|
+
|
170
|
+
if sleep_time > 0
|
171
|
+
Thread.pass
|
172
|
+
sleep sleep_time
|
173
|
+
end
|
166
174
|
end
|
167
175
|
end
|
176
|
+
|
177
|
+
def time
|
178
|
+
start = gettime
|
179
|
+
yield
|
180
|
+
Sidetiq.config.resolution - (gettime.to_f - start.to_f)
|
181
|
+
end
|
168
182
|
end
|
169
183
|
end
|
170
|
-
|
data/lib/sidetiq/middleware.rb
CHANGED
data/lib/sidetiq/schedulable.rb
CHANGED
@@ -12,12 +12,28 @@ module Sidetiq
|
|
12
12
|
# end
|
13
13
|
module Schedulable
|
14
14
|
module ClassMethods
|
15
|
+
def last_scheduled_occurrence
|
16
|
+
get_timestamp "last"
|
17
|
+
end
|
18
|
+
|
19
|
+
def next_scheduled_occurrence
|
20
|
+
get_timestamp "next"
|
21
|
+
end
|
22
|
+
|
15
23
|
def tiq(&block) # :nodoc:
|
16
24
|
clock = Sidetiq::Clock.instance
|
17
25
|
clock.synchronize do
|
18
26
|
clock.schedule_for(self).instance_eval(&block)
|
19
27
|
end
|
20
28
|
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def get_timestamp(key)
|
33
|
+
Sidekiq.redis do |redis|
|
34
|
+
(redis.get("sidetiq:#{name}:#{key}") || -1).to_f
|
35
|
+
end
|
36
|
+
end
|
21
37
|
end
|
22
38
|
|
23
39
|
def self.included(klass) # :nodoc:
|
@@ -25,4 +41,3 @@ module Sidetiq
|
|
25
41
|
end
|
26
42
|
end
|
27
43
|
end
|
28
|
-
|
data/lib/sidetiq/version.rb
CHANGED
@@ -5,10 +5,10 @@ module Sidetiq
|
|
5
5
|
MAJOR = 0
|
6
6
|
|
7
7
|
# Public: Sidetiq minor version number.
|
8
|
-
MINOR =
|
8
|
+
MINOR = 2
|
9
9
|
|
10
10
|
# Public: Sidetiq patch level.
|
11
|
-
PATCH =
|
11
|
+
PATCH = 0
|
12
12
|
|
13
13
|
# Public: String representation of the current Sidetiq version.
|
14
14
|
STRING = [MAJOR, MINOR, PATCH].compact.join('.')
|
data/sidetiq.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.version = Sidetiq::VERSION::STRING
|
9
9
|
gem.authors = ["Tobias Svensson"]
|
10
10
|
gem.email = ["tob@tobiassvensson.co.uk"]
|
11
|
-
gem.description = "
|
11
|
+
gem.description = "Recurring jobs for Sidekiq"
|
12
12
|
gem.summary = gem.description
|
13
13
|
gem.homepage = "http://github.com/tobiassvn/sidetiq"
|
14
14
|
gem.license = "MIT"
|
@@ -19,6 +19,6 @@ Gem::Specification.new do |gem|
|
|
19
19
|
gem.require_paths = ["lib"]
|
20
20
|
gem.extensions = ['ext/sidetiq_ext/extconf.rb']
|
21
21
|
|
22
|
-
gem.add_dependency 'sidekiq', '~> 2.
|
23
|
-
gem.add_dependency 'ice_cube', '~> 0.
|
22
|
+
gem.add_dependency 'sidekiq', '~> 2.8.0'
|
23
|
+
gem.add_dependency 'ice_cube', '~> 0.10.0'
|
24
24
|
end
|
data/test/helper.rb
CHANGED
data/test/test_clock.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
require_relative 'helper'
|
2
2
|
|
3
3
|
class TestClock < Sidetiq::TestCase
|
4
|
-
class FakeWorker
|
4
|
+
class FakeWorker
|
5
|
+
def perform
|
6
|
+
end
|
5
7
|
end
|
6
8
|
|
7
9
|
def test_delegates_to_instance
|
@@ -61,5 +63,72 @@ class TestClock < Sidetiq::TestCase
|
|
61
63
|
clock.tick
|
62
64
|
clock.tick
|
63
65
|
end
|
64
|
-
end
|
65
66
|
|
67
|
+
class LastTickWorker
|
68
|
+
def perform last_tick
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_enqueues_jobs_with_default_last_tick_arg_on_first_run
|
73
|
+
schedule = Sidetiq::Schedule.new(Sidetiq::Clock::START_TIME)
|
74
|
+
schedule.hourly
|
75
|
+
|
76
|
+
time = Time.local(2011, 1, 1, 1, 30)
|
77
|
+
|
78
|
+
clock.stubs(:gettime).returns(time, time + 3600)
|
79
|
+
clock.stubs(:schedules).returns(LastTickWorker => schedule)
|
80
|
+
|
81
|
+
expected_first_tick = time + 1800
|
82
|
+
expected_second_tick = expected_first_tick + 3600
|
83
|
+
|
84
|
+
LastTickWorker.expects(:perform_at).with(expected_first_tick, -1).once
|
85
|
+
LastTickWorker.expects(:perform_at).with(expected_second_tick, expected_first_tick.to_f).once
|
86
|
+
|
87
|
+
clock.tick
|
88
|
+
clock.tick
|
89
|
+
end
|
90
|
+
|
91
|
+
class LastAndScheduledTicksWorker
|
92
|
+
def perform last_tick, scheduled_tick
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_enqueues_jobs_with_last_run_timestamp_and_next_run_timestamp
|
97
|
+
schedule = Sidetiq::Schedule.new(Sidetiq::Clock::START_TIME)
|
98
|
+
schedule.hourly
|
99
|
+
|
100
|
+
time = Time.local(2011, 1, 1, 1, 30)
|
101
|
+
|
102
|
+
clock.stubs(:gettime).returns(time, time + 3600)
|
103
|
+
clock.stubs(:schedules).returns(LastAndScheduledTicksWorker => schedule)
|
104
|
+
|
105
|
+
expected_first_tick = time + 1800
|
106
|
+
expected_second_tick = expected_first_tick + 3600
|
107
|
+
|
108
|
+
LastAndScheduledTicksWorker.expects(:perform_at).with(expected_first_tick, -1, expected_first_tick.to_f).once
|
109
|
+
clock.tick
|
110
|
+
|
111
|
+
LastAndScheduledTicksWorker.expects(:perform_at).with(expected_second_tick, expected_first_tick.to_f, expected_second_tick.to_f).once
|
112
|
+
clock.tick
|
113
|
+
end
|
114
|
+
|
115
|
+
class SplatArgsWorker
|
116
|
+
def perform arg1, *args
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_enqueues_jobs_correctly_for_splat_args_perform_methods
|
121
|
+
schedule = Sidetiq::Schedule.new(Sidetiq::Clock::START_TIME)
|
122
|
+
schedule.hourly
|
123
|
+
|
124
|
+
time = Time.local(2011, 1, 1, 1, 30)
|
125
|
+
|
126
|
+
clock.stubs(:gettime).returns(time, time + 3600)
|
127
|
+
clock.stubs(:schedules).returns(SplatArgsWorker => schedule)
|
128
|
+
|
129
|
+
expected_first_tick = time + 1800
|
130
|
+
|
131
|
+
SplatArgsWorker.expects(:perform_at).with(expected_first_tick, -1, expected_first_tick.to_f).once
|
132
|
+
clock.tick
|
133
|
+
end
|
134
|
+
end
|
data/test/test_worker.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
class TestWorker < Sidetiq::TestCase
|
4
|
+
class FakeWorker
|
5
|
+
include Sidetiq::Schedulable
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_timestamps_for_new_worker
|
9
|
+
assert FakeWorker.last_scheduled_occurrence == -1
|
10
|
+
assert FakeWorker.next_scheduled_occurrence == -1
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_timestamps_for_existing_worker
|
14
|
+
last_run = (Time.now - 100).to_f
|
15
|
+
next_run = (Time.now + 100).to_f
|
16
|
+
|
17
|
+
Sidekiq.redis do |redis|
|
18
|
+
redis.set "sidetiq:TestWorker::FakeWorker:last", last_run
|
19
|
+
redis.set "sidetiq:TestWorker::FakeWorker:next", next_run
|
20
|
+
end
|
21
|
+
|
22
|
+
assert FakeWorker.last_scheduled_occurrence == last_run
|
23
|
+
assert FakeWorker.next_scheduled_occurrence == next_run
|
24
|
+
end
|
25
|
+
end
|
metadata
CHANGED
@@ -2,21 +2,21 @@
|
|
2
2
|
name: sidetiq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.2.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Tobias Svensson
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-03-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
version_requirements: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.
|
19
|
+
version: 2.8.0
|
20
20
|
none: false
|
21
21
|
name: sidekiq
|
22
22
|
type: :runtime
|
@@ -25,14 +25,14 @@ dependencies:
|
|
25
25
|
requirements:
|
26
26
|
- - ~>
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: 2.
|
28
|
+
version: 2.8.0
|
29
29
|
none: false
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
version_requirements: !ruby/object:Gem::Requirement
|
32
32
|
requirements:
|
33
33
|
- - ~>
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: 0.
|
35
|
+
version: 0.10.0
|
36
36
|
none: false
|
37
37
|
name: ice_cube
|
38
38
|
type: :runtime
|
@@ -41,9 +41,9 @@ dependencies:
|
|
41
41
|
requirements:
|
42
42
|
- - ~>
|
43
43
|
- !ruby/object:Gem::Version
|
44
|
-
version: 0.
|
44
|
+
version: 0.10.0
|
45
45
|
none: false
|
46
|
-
description:
|
46
|
+
description: Recurring jobs for Sidekiq
|
47
47
|
email:
|
48
48
|
- tob@tobiassvensson.co.uk
|
49
49
|
executables: []
|
@@ -81,6 +81,7 @@ files:
|
|
81
81
|
- test/test_schedule.rb
|
82
82
|
- test/test_version.rb
|
83
83
|
- test/test_web.rb
|
84
|
+
- test/test_worker.rb
|
84
85
|
homepage: http://github.com/tobiassvn/sidetiq
|
85
86
|
licenses:
|
86
87
|
- MIT
|
@@ -105,7 +106,7 @@ rubyforge_project:
|
|
105
106
|
rubygems_version: 1.8.23
|
106
107
|
signing_key:
|
107
108
|
specification_version: 3
|
108
|
-
summary:
|
109
|
+
summary: Recurring jobs for Sidekiq
|
109
110
|
test_files:
|
110
111
|
- test/helper.rb
|
111
112
|
- test/test_clock.rb
|
@@ -115,4 +116,5 @@ test_files:
|
|
115
116
|
- test/test_schedule.rb
|
116
117
|
- test/test_version.rb
|
117
118
|
- test/test_web.rb
|
119
|
+
- test/test_worker.rb
|
118
120
|
has_rdoc:
|