clockwork 0.7.0 → 0.7.1
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 +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
|