clockwork 0.7.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -0
- data/README.md +62 -28
- data/clockwork.gemspec +1 -1
- data/example.rb +11 -0
- data/gemfiles/activesupport3.gemfile +6 -0
- data/gemfiles/activesupport4.gemfile +6 -0
- data/lib/clockwork/at.rb +19 -12
- data/lib/clockwork/event.rb +20 -31
- data/lib/clockwork/manager.rb +21 -33
- data/test/at_test.rb +6 -0
- data/test/clockwork_test.rb +43 -24
- data/test/event_test.rb +37 -0
- data/test/manager_test.rb +5 -31
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a74c88bbd2e1b38f7c518683c73ec55b7423177
|
4
|
+
data.tar.gz: 45570c06ce685ab483372bd878106fe4569dd6b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59e7b18661134d41a859fb951e1c2e00a48b530bc9b57edd4f52a0bba46385f5f0033a001b3a7d99d8e574e7bf88bc8cb19578849d81b0e18f7b858d7250fa60
|
7
|
+
data.tar.gz: bd9de6f34fffc5a23a63bce5aa805bb9a01fb259c3ce07484ef4b63d7c0bca1a6b558870d0456d33bdf08ab39f75ec07605e99aa4564bc09c2051ef2e707bf54
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -70,13 +70,13 @@ makes it impossible to parallelize. For doing the work, you should be using a
|
|
70
70
|
job queueing system, such as
|
71
71
|
[Delayed Job](http://www.therailsway.com/2009/7/22/do-it-later-with-delayed-job),
|
72
72
|
[Beanstalk/Stalker](http://adam.heroku.com/past/2010/4/24/beanstalk_a_simple_and_fast_queueing_backend/),
|
73
|
-
[RabbitMQ/Minion](http://
|
73
|
+
[RabbitMQ/Minion](http://adam.heroku.com/past/2009/9/28/background_jobs_with_rabbitmq_and_minion/),
|
74
74
|
[Resque](http://github.com/blog/542-introducing-resque), or
|
75
75
|
[Sidekiq](https://github.com/mperham/sidekiq). This design allows a
|
76
76
|
simple clock process with no locks, but also offers near infinite horizontal
|
77
77
|
scalability.
|
78
78
|
|
79
|
-
For example, if you're using Beanstalk/
|
79
|
+
For example, if you're using Beanstalk/Stalker:
|
80
80
|
|
81
81
|
```ruby
|
82
82
|
require 'stalker'
|
@@ -103,12 +103,22 @@ every(1.hour, 'feeds.refresh') { Feed.send_later(:refresh) }
|
|
103
103
|
every(1.day, 'reminders.send', :at => '01:30') { Reminder.send_later(:send_reminders) }
|
104
104
|
```
|
105
105
|
|
106
|
-
Parameters
|
106
|
+
Event Parameters
|
107
107
|
----------
|
108
108
|
|
109
109
|
### :at
|
110
110
|
|
111
|
-
`:at` parameter
|
111
|
+
`:at` parameter specifies when to trigger the event:
|
112
|
+
|
113
|
+
#### Valid formats:
|
114
|
+
|
115
|
+
HH:MM
|
116
|
+
H:MM
|
117
|
+
**:MM
|
118
|
+
HH:**
|
119
|
+
(Mon|mon|Monday|monday) HH:MM
|
120
|
+
|
121
|
+
#### Examples
|
112
122
|
|
113
123
|
The simplest example:
|
114
124
|
|
@@ -116,13 +126,13 @@ The simplest example:
|
|
116
126
|
every(1.day, 'reminders.send', :at => '01:30')
|
117
127
|
```
|
118
128
|
|
119
|
-
You can omit 0 of the hour:
|
129
|
+
You can omit the leading 0 of the hour:
|
120
130
|
|
121
131
|
```ruby
|
122
132
|
every(1.day, 'reminders.send', :at => '1:30')
|
123
133
|
```
|
124
134
|
|
125
|
-
|
135
|
+
Wildcards for hour and minute are supported:
|
126
136
|
|
127
137
|
```ruby
|
128
138
|
every(1.hour, 'reminders.send', :at => '**:30')
|
@@ -132,7 +142,7 @@ every(10.seconds, 'frequent.job', :at => '9:**')
|
|
132
142
|
You can set more than one timing:
|
133
143
|
|
134
144
|
```ruby
|
135
|
-
every(1.
|
145
|
+
every(1.day, 'reminders.send', :at => ['12:00', '18:00'])
|
136
146
|
# send reminders at noon and evening
|
137
147
|
```
|
138
148
|
|
@@ -142,7 +152,9 @@ You can specify the day of week to run:
|
|
142
152
|
every(1.week, 'myjob', :at => 'Monday 16:20')
|
143
153
|
```
|
144
154
|
|
145
|
-
|
155
|
+
### :tz
|
156
|
+
|
157
|
+
`:tz` parameter lets you specify a timezone (default is the local timezone):
|
146
158
|
|
147
159
|
```ruby
|
148
160
|
every(1.day, 'reminders.send', :at => '00:00', :tz => 'UTC')
|
@@ -171,36 +183,44 @@ Clockwork.every(1.second, 'myjob', :if => lambda { |_| true })
|
|
171
183
|
|
172
184
|
### :thread
|
173
185
|
|
174
|
-
|
186
|
+
An event with `:thread => true` runs in a different thread.
|
175
187
|
|
176
|
-
|
188
|
+
```ruby
|
189
|
+
Clockwork.every(1.day, 'run.me.in.new.thread', :thread => true)
|
190
|
+
```
|
191
|
+
|
192
|
+
If a job is long-running or IO-intensive, this option helps keep the clock precise.
|
177
193
|
|
178
194
|
Configuration
|
179
195
|
-----------------------
|
180
196
|
|
181
|
-
Clockwork exposes a couple of configuration options
|
197
|
+
Clockwork exposes a couple of configuration options:
|
182
198
|
|
183
199
|
### :logger
|
184
200
|
|
185
|
-
By default Clockwork logs to STDOUT
|
201
|
+
By default Clockwork logs to `STDOUT`. In case you prefer your
|
186
202
|
own logger implementation you have to specify the `logger` configuration option. See example below.
|
187
203
|
|
188
204
|
### :sleep_timeout
|
189
205
|
|
190
|
-
Clockwork wakes up once a second
|
191
|
-
|
192
|
-
the `sleep_timeout` configuration option to set like shown below.
|
206
|
+
Clockwork wakes up once a second and performs its duties. To change the number of seconds Clockwork
|
207
|
+
sleeps, set the `sleep_timeout` configuration option as shown below in the example.
|
193
208
|
|
194
209
|
### :tz
|
195
210
|
|
196
211
|
This is the default timezone to use for all events. When not specified this defaults to the local
|
197
|
-
timezone. Specifying :tz in the
|
212
|
+
timezone. Specifying :tz in the parameters for an event overrides anything set here.
|
198
213
|
|
199
214
|
### :max_threads
|
200
215
|
|
201
|
-
Clockwork runs handlers in threads. If it exceeds `max_threads`, it will warn you about missing
|
216
|
+
Clockwork runs handlers in threads. If it exceeds `max_threads`, it will warn you (log an error) about missing
|
202
217
|
jobs.
|
203
218
|
|
219
|
+
|
220
|
+
### :thread
|
221
|
+
|
222
|
+
Boolean true or false. Default is false. If set to true, every event will be run in its own thread. Can be overridden on a per event basis (see the ```:thread``` option in the Event Parameters section above)
|
223
|
+
|
204
224
|
### Configuration example
|
205
225
|
|
206
226
|
```ruby
|
@@ -210,6 +230,7 @@ module Clockwork
|
|
210
230
|
config[:logger] = Logger.new(log_file_path)
|
211
231
|
config[:tz] = 'EST'
|
212
232
|
config[:max_threads] = 15
|
233
|
+
config[:thread] = true
|
213
234
|
end
|
214
235
|
end
|
215
236
|
```
|
@@ -229,7 +250,7 @@ end
|
|
229
250
|
Current specifications are as follows.
|
230
251
|
|
231
252
|
- defining error_handler does not disable original logging
|
232
|
-
- errors from error_handler itself
|
253
|
+
- errors from error_handler itself are not rescued, and stop clockwork
|
233
254
|
|
234
255
|
Any suggestion about these specifications is welcome.
|
235
256
|
|
@@ -237,7 +258,7 @@ Old style
|
|
237
258
|
---------
|
238
259
|
|
239
260
|
`include Clockwork` is old style.
|
240
|
-
|
261
|
+
The old style is still supported, though not recommended, because it pollutes the global namespace.
|
241
262
|
|
242
263
|
|
243
264
|
|
@@ -246,8 +267,7 @@ Anatomy of a clock file
|
|
246
267
|
|
247
268
|
clock.rb is standard Ruby. Since we include the Clockwork module (the
|
248
269
|
clockwork binary does this automatically, or you can do it explicitly), this
|
249
|
-
exposes a small DSL
|
250
|
-
and then the events themselves.
|
270
|
+
exposes a small DSL to define the handler for events, and then the events themselves.
|
251
271
|
|
252
272
|
The handler typically looks like this:
|
253
273
|
|
@@ -259,7 +279,7 @@ This block will be invoked every time an event is triggered, with the job name
|
|
259
279
|
passed in. In most cases, you should be able to pass the job name directly
|
260
280
|
through to your queueing system.
|
261
281
|
|
262
|
-
The second part of the file
|
282
|
+
The second part of the file, which lists the events, roughly resembles a crontab:
|
263
283
|
|
264
284
|
```ruby
|
265
285
|
every(5.minutes, 'thing.do')
|
@@ -286,7 +306,21 @@ You can also use blocks to do more complex checks:
|
|
286
306
|
|
287
307
|
```ruby
|
288
308
|
every(1.day, 'check.leap.year') do
|
289
|
-
Stalker.enqueue('leap.year.party') if Time.now.year
|
309
|
+
Stalker.enqueue('leap.year.party') if Date.leap?(Time.now.year)
|
310
|
+
end
|
311
|
+
```
|
312
|
+
|
313
|
+
In addition, Clockwork also supports `:before_tick` and `after_tick` callbacks.
|
314
|
+
They are optional, and run every tick (a tick being whatever your `:sleep_timeout`
|
315
|
+
is set to, default is 1 second):
|
316
|
+
|
317
|
+
```ruby
|
318
|
+
on(:before_tick) do
|
319
|
+
puts "tick"
|
320
|
+
end
|
321
|
+
|
322
|
+
on(:after_tick) do
|
323
|
+
puts "tock"
|
290
324
|
end
|
291
325
|
```
|
292
326
|
|
@@ -307,9 +341,9 @@ running the same way you keep your web and workers running.
|
|
307
341
|
Daemonization
|
308
342
|
-------------
|
309
343
|
|
310
|
-
Thanks to @fddayan, `clockworkd` executes clockwork script
|
344
|
+
Thanks to @fddayan, `clockworkd` executes clockwork script as a daemon.
|
311
345
|
|
312
|
-
You need `daemons` gem to use `clockworkd`. It is not automatically installed, please install by yourself.
|
346
|
+
You will need the `daemons` gem to use `clockworkd`. It is not automatically installed, please install by yourself.
|
313
347
|
|
314
348
|
Then,
|
315
349
|
|
@@ -322,15 +356,15 @@ For more details, see help shown by `clockworkd`.
|
|
322
356
|
Issues and Pull requests
|
323
357
|
------------------------
|
324
358
|
|
325
|
-
|
359
|
+
If you find a bug, please create an issue - [Issues · tomykaira/clockwork](https://github.com/tomykaira/clockwork/issues).
|
326
360
|
|
327
361
|
For a bug fix or a feature request, please send a pull-request.
|
328
362
|
Do not forget to add tests to show how your feature works, or what bug is fixed.
|
329
363
|
All existing tests and new tests must pass (TravisCI is watching).
|
330
364
|
|
331
365
|
We want to provide simple and customizable core, so superficial changes will not be merged (e.g. supporting new event registration style).
|
332
|
-
In most
|
333
|
-
If you
|
366
|
+
In most cases, directly operating `Manager` realizes an idea, without touching the core.
|
367
|
+
If you discover a new way to use Clockwork, please create a gist page or an article on your website, then add it to the following "Use cases" section.
|
334
368
|
This tool is already used in various environment, so backward-incompatible requests will be mostly rejected.
|
335
369
|
|
336
370
|
Use cases
|
data/clockwork.gemspec
CHANGED
data/example.rb
CHANGED
@@ -14,4 +14,15 @@ module Clockwork
|
|
14
14
|
every(1.day, 'custom.event.handler', :at => '00:30') do
|
15
15
|
puts 'This event has its own handler'
|
16
16
|
end
|
17
|
+
|
18
|
+
# note: callbacks that return nil or false will cause event to not run
|
19
|
+
on(:before_tick) do
|
20
|
+
puts "tick"
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
on(:after_tick) do
|
25
|
+
puts "tock"
|
26
|
+
true
|
27
|
+
end
|
17
28
|
end
|
data/lib/clockwork/at.rb
CHANGED
@@ -3,19 +3,23 @@ module Clockwork
|
|
3
3
|
class FailedToParse < StandardError; end
|
4
4
|
|
5
5
|
NOT_SPECIFIED = nil
|
6
|
-
WDAYS = %w[sunday monday tuesday wednesday thursday friday saturday].
|
7
|
-
[w, w.capitalize, w[0...3], w[0...3].capitalize]
|
6
|
+
WDAYS = %w[sunday monday tuesday wednesday thursday friday saturday].each.with_object({}).with_index do |(w, wdays), index|
|
7
|
+
[w, w.capitalize, w[0...3], w[0...3].capitalize].each do |k|
|
8
|
+
wdays[k] = index
|
9
|
+
end
|
8
10
|
end
|
9
11
|
|
10
12
|
def self.parse(at)
|
11
13
|
return unless at
|
12
14
|
case at
|
13
15
|
when /^([[:alpha:]]+)\s(.*)$/
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
if wday = WDAYS[$1]
|
17
|
+
parsed_time = parse($2)
|
18
|
+
parsed_time.wday = wday
|
19
|
+
parsed_time
|
20
|
+
else
|
21
|
+
raise FailedToParse, at
|
22
|
+
end
|
19
23
|
when /^(\d{1,2}):(\d\d)$/
|
20
24
|
new($2.to_i, $1.to_i)
|
21
25
|
when /^\*{1,2}:(\d\d)$/
|
@@ -32,14 +36,10 @@ module Clockwork
|
|
32
36
|
attr_writer :min, :hour, :wday
|
33
37
|
|
34
38
|
def initialize(min, hour=NOT_SPECIFIED, wday=NOT_SPECIFIED)
|
35
|
-
if (min != NOT_SPECIFIED && (min < 0 || min > 59)) ||
|
36
|
-
(hour != NOT_SPECIFIED && (hour < 0 || hour > 23)) ||
|
37
|
-
(wday != NOT_SPECIFIED && (wday < 0 || wday > 6))
|
38
|
-
raise ArgumentError
|
39
|
-
end
|
40
39
|
@min = min
|
41
40
|
@hour = hour
|
42
41
|
@wday = wday
|
42
|
+
raise ArgumentError unless valid?
|
43
43
|
end
|
44
44
|
|
45
45
|
def ready?(t)
|
@@ -47,5 +47,12 @@ module Clockwork
|
|
47
47
|
(@hour == NOT_SPECIFIED or t.hour == @hour) and
|
48
48
|
(@wday == NOT_SPECIFIED or t.wday == @wday)
|
49
49
|
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def valid?
|
53
|
+
@min == NOT_SPECIFIED || (0..59).cover?(@min) &&
|
54
|
+
@hour == NOT_SPECIFIED || (0..23).cover?(@hour) &&
|
55
|
+
@wday == NOT_SPECIFIED || (0..6).cover?(@wday)
|
56
|
+
end
|
50
57
|
end
|
51
58
|
end
|
data/lib/clockwork/event.rb
CHANGED
@@ -3,6 +3,7 @@ module Clockwork
|
|
3
3
|
attr_accessor :job, :last
|
4
4
|
|
5
5
|
def initialize(manager, period, job, block, options={})
|
6
|
+
validate_if_option(options[:if])
|
6
7
|
@manager = manager
|
7
8
|
@period = period
|
8
9
|
@job = job
|
@@ -10,22 +11,17 @@ module Clockwork
|
|
10
11
|
@last = nil
|
11
12
|
@block = block
|
12
13
|
@if = options[:if]
|
13
|
-
@thread = options[:thread]
|
14
|
-
@timezone = options[:tz]
|
15
|
-
end
|
16
|
-
|
17
|
-
def to_s
|
18
|
-
@job
|
14
|
+
@thread = options.fetch(:thread, @manager.config[:thread])
|
15
|
+
@timezone = options.fetch(:tz, @manager.config[:tz])
|
19
16
|
end
|
20
17
|
|
21
18
|
def convert_timezone(t)
|
22
19
|
@timezone ? t.in_time_zone(@timezone) : t
|
23
20
|
end
|
24
21
|
|
25
|
-
def
|
22
|
+
def run_now?(t)
|
26
23
|
t = convert_timezone(t)
|
27
|
-
elapsed_ready
|
28
|
-
elapsed_ready and (@at.nil? or @at.ready?(t)) and (@if.nil? or @if.call(t))
|
24
|
+
elapsed_ready(t) and (@at.nil? or @at.ready?(t)) and (@if.nil? or @if.call(t))
|
29
25
|
end
|
30
26
|
|
31
27
|
def thread?
|
@@ -33,45 +29,38 @@ module Clockwork
|
|
33
29
|
end
|
34
30
|
|
35
31
|
def run(t)
|
36
|
-
|
37
|
-
@last = t
|
38
|
-
|
32
|
+
@manager.log "Triggering '#{self}'"
|
33
|
+
@last = convert_timezone(t)
|
39
34
|
if thread?
|
40
35
|
if @manager.thread_available?
|
41
36
|
Thread.new { execute }
|
42
37
|
else
|
43
|
-
log_error "Threads exhausted; skipping #{self}"
|
38
|
+
@manager.log_error "Threads exhausted; skipping #{self}"
|
44
39
|
end
|
45
40
|
else
|
46
41
|
execute
|
47
42
|
end
|
48
43
|
end
|
49
44
|
|
45
|
+
def to_s
|
46
|
+
job.to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
50
|
def execute
|
51
51
|
@block.call(@job, @last)
|
52
52
|
rescue => e
|
53
|
-
log_error e
|
54
|
-
handle_error e
|
55
|
-
end
|
56
|
-
|
57
|
-
def log_error(e)
|
58
|
-
@manager.config[:logger].error(e)
|
53
|
+
@manager.log_error e
|
54
|
+
@manager.handle_error e
|
59
55
|
end
|
60
56
|
|
61
|
-
def
|
62
|
-
|
63
|
-
|
64
|
-
base = File.expand_path(Dir.pwd) + '/'
|
65
|
-
e.backtrace.each do |t|
|
66
|
-
msg << " #{File.expand_path(t).gsub(/#{base}/, '')}"
|
67
|
-
end
|
68
|
-
|
69
|
-
msg.join("\n")
|
57
|
+
def elapsed_ready(t)
|
58
|
+
@last.nil? || (t - @last).to_i >= @period
|
70
59
|
end
|
71
60
|
|
72
|
-
def
|
73
|
-
if
|
74
|
-
|
61
|
+
def validate_if_option(if_option)
|
62
|
+
if if_option && !if_option.respond_to?(:call)
|
63
|
+
raise ArgumentError.new(':if expects a callable object, but #{if_option} does not respond to call')
|
75
64
|
end
|
76
65
|
end
|
77
66
|
end
|
data/lib/clockwork/manager.rb
CHANGED
@@ -24,19 +24,13 @@ module Clockwork
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def handler(&block)
|
27
|
-
@handler = block
|
28
|
-
|
29
|
-
|
30
|
-
def get_handler
|
31
|
-
raise NoHandlerDefined unless (defined?(@handler) and @handler)
|
27
|
+
@handler = block if block_given?
|
28
|
+
raise NoHandlerDefined unless @handler
|
32
29
|
@handler
|
33
30
|
end
|
34
31
|
|
35
32
|
def error_handler(&block)
|
36
|
-
@error_handler = block
|
37
|
-
end
|
38
|
-
|
39
|
-
def get_error_handler
|
33
|
+
@error_handler = block if block_given?
|
40
34
|
@error_handler
|
41
35
|
end
|
42
36
|
|
@@ -58,7 +52,7 @@ module Clockwork
|
|
58
52
|
end
|
59
53
|
|
60
54
|
def run
|
61
|
-
log "Starting clock for #{@events.size} events: [
|
55
|
+
log "Starting clock for #{@events.size} events: [ #{@events.map(&:to_s).join(' ')} ]"
|
62
56
|
loop do
|
63
57
|
tick
|
64
58
|
sleep(config[:sleep_timeout])
|
@@ -67,47 +61,41 @@ module Clockwork
|
|
67
61
|
|
68
62
|
def tick(t=Time.now)
|
69
63
|
if (fire_callbacks(:before_tick))
|
70
|
-
|
71
|
-
|
72
|
-
end
|
73
|
-
|
74
|
-
to_run.each do |event|
|
64
|
+
events = events_to_run(t)
|
65
|
+
events.each do |event|
|
75
66
|
if (fire_callbacks(:before_run, event, t))
|
76
|
-
log "Triggering '#{event}'"
|
77
67
|
event.run(t)
|
78
68
|
fire_callbacks(:after_run, event, t)
|
79
69
|
end
|
80
70
|
end
|
81
71
|
end
|
82
|
-
|
83
72
|
fire_callbacks(:after_tick)
|
84
|
-
|
73
|
+
events
|
74
|
+
end
|
75
|
+
|
76
|
+
def log_error(e)
|
77
|
+
config[:logger].error(e)
|
78
|
+
end
|
79
|
+
|
80
|
+
def handle_error(e)
|
81
|
+
error_handler.call(e) if error_handler
|
85
82
|
end
|
86
83
|
|
87
|
-
private
|
88
84
|
def log(msg)
|
89
85
|
config[:logger].info(msg)
|
90
86
|
end
|
91
87
|
|
88
|
+
private
|
89
|
+
def events_to_run(t)
|
90
|
+
@events.select{ |event| event.run_now?(t) }
|
91
|
+
end
|
92
|
+
|
92
93
|
def register(period, job, block, options)
|
93
|
-
event = Event.new(self, period, job, block ||
|
94
|
+
event = Event.new(self, period, job, block || handler, options)
|
94
95
|
@events << event
|
95
96
|
event
|
96
97
|
end
|
97
98
|
|
98
|
-
def parse_event_option(options)
|
99
|
-
if options[:if]
|
100
|
-
if !options[:if].respond_to?(:call)
|
101
|
-
raise ArgumentError.new(':if expects a callable object, but #{options[:if]} does not respond to call')
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
options[:thread] = !!(options.has_key?(:thread) ? options[:thread] : config[:thread])
|
106
|
-
options[:tz] ||= config[:tz]
|
107
|
-
|
108
|
-
options
|
109
|
-
end
|
110
|
-
|
111
99
|
def every_with_multiple_times(period, job, options={}, &block)
|
112
100
|
each_options = options.clone
|
113
101
|
options[:at].each do |at|
|
data/test/at_test.rb
CHANGED
@@ -84,4 +84,10 @@ class AtTest < Test::Unit::TestCase
|
|
84
84
|
assert at.ready?(Time.new(2010, 1, 2, 12, 00))
|
85
85
|
assert !at.ready?(Time.new(2010, 1, 3, 12, 00))
|
86
86
|
end
|
87
|
+
|
88
|
+
test 'invalid time 32:00' do
|
89
|
+
assert_raise Clockwork::At::FailedToParse do
|
90
|
+
Clockwork::At.parse('32:00')
|
91
|
+
end
|
92
|
+
end
|
87
93
|
end
|
data/test/clockwork_test.rb
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
require File.expand_path('../../lib/clockwork', __FILE__)
|
2
2
|
require 'contest'
|
3
|
-
require '
|
3
|
+
require 'mocha/setup'
|
4
4
|
|
5
5
|
class ClockworkTest < Test::Unit::TestCase
|
6
|
+
setup do
|
7
|
+
Clockwork.configure do |config|
|
8
|
+
config[:sleep_timeout] = 0
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
6
12
|
teardown do
|
7
13
|
Clockwork.clear!
|
8
14
|
end
|
@@ -15,12 +21,6 @@ class ClockworkTest < Test::Unit::TestCase
|
|
15
21
|
string_io
|
16
22
|
end
|
17
23
|
|
18
|
-
def run_in_thread
|
19
|
-
Thread.new do
|
20
|
-
Clockwork.run
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
24
|
test 'should run events with configured logger' do
|
25
25
|
run = false
|
26
26
|
string_io = set_string_io_logger
|
@@ -28,34 +28,55 @@ class ClockworkTest < Test::Unit::TestCase
|
|
28
28
|
run = job == 'myjob'
|
29
29
|
end
|
30
30
|
Clockwork.every(1.minute, 'myjob')
|
31
|
+
Clockwork.manager.expects(:loop).yields.then.returns
|
32
|
+
Clockwork.run
|
33
|
+
assert run
|
34
|
+
assert string_io.string.include?('Triggering')
|
35
|
+
end
|
31
36
|
|
32
|
-
|
37
|
+
test 'should log event correctly' do
|
38
|
+
run = false
|
39
|
+
string_io = set_string_io_logger
|
40
|
+
Clockwork.handler do |job|
|
41
|
+
run = job == 'an event'
|
42
|
+
end
|
43
|
+
Clockwork.every(1.minute, 'an event')
|
44
|
+
Clockwork.manager.expects(:loop).yields.then.returns
|
45
|
+
Clockwork.run
|
46
|
+
assert run
|
47
|
+
assert string_io.string.include?("Triggering 'an event'")
|
48
|
+
end
|
33
49
|
|
34
|
-
|
35
|
-
|
50
|
+
test 'should pass event without modification to handler' do
|
51
|
+
event_object = Object.new
|
52
|
+
run = false
|
53
|
+
string_io = set_string_io_logger
|
54
|
+
Clockwork.handler do |job|
|
55
|
+
run = job == event_object
|
36
56
|
end
|
37
|
-
|
57
|
+
Clockwork.every(1.minute, event_object)
|
58
|
+
Clockwork.manager.expects(:loop).yields.then.returns
|
59
|
+
Clockwork.run
|
38
60
|
assert run
|
39
|
-
assert string_io.string.include?('Triggering')
|
40
61
|
end
|
41
62
|
|
42
63
|
test 'should not run anything after reset' do
|
43
64
|
Clockwork.every(1.minute, 'myjob') { }
|
44
65
|
Clockwork.clear!
|
45
|
-
|
66
|
+
Clockwork.configure do |config|
|
67
|
+
config[:sleep_timeout] = 0
|
68
|
+
end
|
46
69
|
string_io = set_string_io_logger
|
47
|
-
|
48
|
-
|
49
|
-
runner.kill
|
70
|
+
Clockwork.manager.expects(:loop).yields.then.returns
|
71
|
+
Clockwork.run
|
50
72
|
assert string_io.string.include?('0 events')
|
51
73
|
end
|
52
74
|
|
53
75
|
test 'should pass all arguments to every' do
|
54
|
-
Clockwork.every(1.second, 'myjob', if: lambda { false }) { }
|
76
|
+
Clockwork.every(1.second, 'myjob', if: lambda { |_| false }) { }
|
55
77
|
string_io = set_string_io_logger
|
56
|
-
|
57
|
-
|
58
|
-
runner.kill
|
78
|
+
Clockwork.manager.expects(:loop).yields.then.returns
|
79
|
+
Clockwork.run
|
59
80
|
assert string_io.string.include?('1 events')
|
60
81
|
assert !string_io.string.include?('Triggering')
|
61
82
|
end
|
@@ -66,10 +87,8 @@ class ClockworkTest < Test::Unit::TestCase
|
|
66
87
|
every(1.second, 'myjob') { $called = true }
|
67
88
|
end
|
68
89
|
set_string_io_logger
|
69
|
-
|
70
|
-
|
71
|
-
runner.kill
|
72
|
-
|
90
|
+
Clockwork.manager.expects(:loop).yields.then.returns
|
91
|
+
Clockwork.run
|
73
92
|
assert $called
|
74
93
|
end
|
75
94
|
end
|
data/test/event_test.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.expand_path('../../lib/clockwork', __FILE__)
|
2
|
+
require 'contest'
|
3
|
+
|
4
|
+
class EventTest < Test::Unit::TestCase
|
5
|
+
describe "#thread?" do
|
6
|
+
setup do
|
7
|
+
@manager = mock
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "manager config thread option set to true" do
|
11
|
+
setup do
|
12
|
+
@manager.stubs(:config).returns({ :thread => true })
|
13
|
+
end
|
14
|
+
|
15
|
+
test "is true" do
|
16
|
+
event = Clockwork::Event.new(@manager, nil, nil, nil)
|
17
|
+
assert_equal true, event.thread?
|
18
|
+
end
|
19
|
+
|
20
|
+
test "is false when event thread option set" do
|
21
|
+
event = Clockwork::Event.new(@manager, nil, nil, nil, :thread => false)
|
22
|
+
assert_equal false, event.thread?
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "manager config thread option not set" do
|
27
|
+
setup do
|
28
|
+
@manager.stubs(:config).returns({})
|
29
|
+
end
|
30
|
+
|
31
|
+
test "is true if event thread option is true" do
|
32
|
+
event = Clockwork::Event.new(@manager, nil, nil, nil, :thread => true)
|
33
|
+
assert_equal true, event.thread?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/test/manager_test.rb
CHANGED
@@ -122,7 +122,7 @@ class ManagerTest < Test::Unit::TestCase
|
|
122
122
|
test "exceptions still set the last timestamp to avoid spastic error loops" do
|
123
123
|
@manager.handler { raise 'boom' }
|
124
124
|
event = @manager.every(1.minute, 'myjob')
|
125
|
-
|
125
|
+
@manager.stubs(:log_error)
|
126
126
|
@manager.tick(t = Time.now)
|
127
127
|
assert_equal t, event.last
|
128
128
|
end
|
@@ -173,6 +173,10 @@ class ManagerTest < Test::Unit::TestCase
|
|
173
173
|
end
|
174
174
|
|
175
175
|
describe ':tz option' do
|
176
|
+
test "time zone is not set by default" do
|
177
|
+
assert @manager.config[:tz].nil?
|
178
|
+
end
|
179
|
+
|
176
180
|
test "should be able to specify a different timezone than local" do
|
177
181
|
@manager.every(1.day, 'myjob', :at => '10:00', :tz => 'UTC')
|
178
182
|
|
@@ -256,36 +260,6 @@ class ManagerTest < Test::Unit::TestCase
|
|
256
260
|
@manager.tick(Time.now)
|
257
261
|
end
|
258
262
|
|
259
|
-
describe "thread option" do
|
260
|
-
test "should not use thread by default" do
|
261
|
-
event = @manager.every(1.minute, 'myjob')
|
262
|
-
assert !event.thread?
|
263
|
-
end
|
264
|
-
|
265
|
-
test "should use thread if thread option is specified with truly value" do
|
266
|
-
event = @manager.every(1.minute, 'myjob', :thread => true)
|
267
|
-
assert event.thread?
|
268
|
-
end
|
269
|
-
|
270
|
-
test "should use thread if global thread option is set" do
|
271
|
-
@manager.configure do |config|
|
272
|
-
config[:thread] = true
|
273
|
-
end
|
274
|
-
|
275
|
-
event = @manager.every(1.minute, 'myjob')
|
276
|
-
assert event.thread?
|
277
|
-
end
|
278
|
-
|
279
|
-
test "should not use thread if job option overrides global option" do
|
280
|
-
@manager.configure do |config|
|
281
|
-
config[:thread] = true
|
282
|
-
end
|
283
|
-
|
284
|
-
event = @manager.every(1.minute, 'myjob', :thread => false)
|
285
|
-
assert !event.thread?
|
286
|
-
end
|
287
|
-
end
|
288
|
-
|
289
263
|
describe "callbacks" do
|
290
264
|
test "should not accept unknown callback name" do
|
291
265
|
assert_raise(RuntimeError, "Unsupported callback unknown_callback") do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clockwork
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Wiggins
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-02-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: tzinfo
|
@@ -138,6 +138,7 @@ files:
|
|
138
138
|
- lib/clockwork/manager.rb
|
139
139
|
- test/at_test.rb
|
140
140
|
- test/clockwork_test.rb
|
141
|
+
- test/event_test.rb
|
141
142
|
- test/manager_test.rb
|
142
143
|
homepage: http://github.com/tomykaira/clockwork
|
143
144
|
licenses:
|
@@ -166,4 +167,5 @@ summary: A scheduler process to replace cron.
|
|
166
167
|
test_files:
|
167
168
|
- test/at_test.rb
|
168
169
|
- test/clockwork_test.rb
|
170
|
+
- test/event_test.rb
|
169
171
|
- test/manager_test.rb
|