clockwork 0.3.4 → 0.4.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/Gemfile +2 -0
- data/Gemfile.lock +2 -0
- data/README.md +35 -0
- data/VERSION +1 -1
- data/lib/clockwork.rb +40 -6
- data/test/clockwork_test.rb +74 -0
- metadata +21 -7
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -119,6 +119,41 @@ You can set more than one timing:
|
|
|
119
119
|
every(1.hour, 'reminders.send', :at => ['12:00', '18:00'])
|
|
120
120
|
# send reminders at noon and evening
|
|
121
121
|
|
|
122
|
+
You can also specify a timezone (default is the local timezone):
|
|
123
|
+
|
|
124
|
+
every(1.day, 'reminders.send', :at => '00:00', :tz => 'UTC')
|
|
125
|
+
# Runs the job each day at midnight, UTC.
|
|
126
|
+
# The value for :tz can be anything supported by [TZInfo](http://tzinfo.rubyforge.org/)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
Configuration
|
|
130
|
+
-----------------------
|
|
131
|
+
|
|
132
|
+
Clockwork exposes a couple of configuration options you may change:
|
|
133
|
+
|
|
134
|
+
### :logger
|
|
135
|
+
|
|
136
|
+
By default Clockwork logs to STDOUT. In case you prefer to make it to use our
|
|
137
|
+
own logger implementation you have to specify the `logger` configuration option. See example below.
|
|
138
|
+
|
|
139
|
+
### :sleep_timeout
|
|
140
|
+
|
|
141
|
+
Clockwork wakes up once a second (by default) and performs its duties. If that
|
|
142
|
+
is the rare case you need to tweak the number of seconds it sleeps then you have
|
|
143
|
+
the `sleep_timeout` configuration option to set like shown below.
|
|
144
|
+
|
|
145
|
+
### :tz
|
|
146
|
+
|
|
147
|
+
This is the default timezone to use for all events. When not specified this defaults to the local
|
|
148
|
+
timezone. Specifying :tz in the the parameters for an event overrides anything set here.
|
|
149
|
+
|
|
150
|
+
### Configuration example
|
|
151
|
+
|
|
152
|
+
Clockwork.configure do |config|
|
|
153
|
+
config[:sleep_timeout] = 5
|
|
154
|
+
config[:logger] = Logger.new(log_file_path)
|
|
155
|
+
config[:tz] = 'EST'
|
|
156
|
+
end
|
|
122
157
|
|
|
123
158
|
Anatomy of a clock file
|
|
124
159
|
-----------------------
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.4.0
|
data/lib/clockwork.rb
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
require 'logger'
|
|
2
|
+
require 'tzinfo'
|
|
3
|
+
|
|
1
4
|
module Clockwork
|
|
2
5
|
|
|
3
6
|
@@events = []
|
|
@@ -58,18 +61,34 @@ module Clockwork
|
|
|
58
61
|
@at = At.parse(options[:at])
|
|
59
62
|
@last = nil
|
|
60
63
|
@block = block
|
|
64
|
+
if options[:if]
|
|
65
|
+
if options[:if].respond_to?(:call)
|
|
66
|
+
@if = options[:if]
|
|
67
|
+
else
|
|
68
|
+
raise ArgumentError.new(':if expects a callable object, but #{options[:if]} does not respond to call')
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
tz = options[:tz] || Clockwork.config[:tz]
|
|
73
|
+
@timezone = TZInfo::Timezone.get(tz) if tz
|
|
61
74
|
end
|
|
62
75
|
|
|
63
76
|
def to_s
|
|
64
77
|
@job
|
|
65
78
|
end
|
|
66
79
|
|
|
80
|
+
def convert_timezone(t)
|
|
81
|
+
@timezone ? @timezone.utc_to_local(t.dup.utc) : t
|
|
82
|
+
end
|
|
83
|
+
|
|
67
84
|
def time?(t)
|
|
68
|
-
|
|
69
|
-
|
|
85
|
+
t = convert_timezone(t)
|
|
86
|
+
elapsed_ready = (@last.nil? or (t - @last).to_i >= @period)
|
|
87
|
+
elapsed_ready and (@at.nil? or @at.ready?(t)) and (@if.nil? or @if.call(t))
|
|
70
88
|
end
|
|
71
89
|
|
|
72
90
|
def run(t)
|
|
91
|
+
t = convert_timezone(t)
|
|
73
92
|
@last = t
|
|
74
93
|
@block.call(@job)
|
|
75
94
|
rescue => e
|
|
@@ -77,7 +96,7 @@ module Clockwork
|
|
|
77
96
|
end
|
|
78
97
|
|
|
79
98
|
def log_error(e)
|
|
80
|
-
|
|
99
|
+
Clockwork.config[:logger].error(e)
|
|
81
100
|
end
|
|
82
101
|
|
|
83
102
|
def exception_message(e)
|
|
@@ -92,8 +111,22 @@ module Clockwork
|
|
|
92
111
|
end
|
|
93
112
|
end
|
|
94
113
|
|
|
114
|
+
def configure
|
|
115
|
+
yield(config)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def config
|
|
119
|
+
@@configuration
|
|
120
|
+
end
|
|
121
|
+
|
|
95
122
|
extend self
|
|
96
123
|
|
|
124
|
+
def default_configuration
|
|
125
|
+
{ :sleep_timeout => 1, :logger => Logger.new(STDOUT) }
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
@@configuration = default_configuration
|
|
129
|
+
|
|
97
130
|
def handler(&block)
|
|
98
131
|
@@handler = block
|
|
99
132
|
end
|
|
@@ -121,12 +154,12 @@ module Clockwork
|
|
|
121
154
|
log "Starting clock for #{@@events.size} events: [ " + @@events.map { |e| e.to_s }.join(' ') + " ]"
|
|
122
155
|
loop do
|
|
123
156
|
tick
|
|
124
|
-
sleep
|
|
157
|
+
sleep(config[:sleep_timeout])
|
|
125
158
|
end
|
|
126
159
|
end
|
|
127
160
|
|
|
128
161
|
def log(msg)
|
|
129
|
-
|
|
162
|
+
config[:logger].info(msg)
|
|
130
163
|
end
|
|
131
164
|
|
|
132
165
|
def tick(t=Time.now)
|
|
@@ -135,7 +168,7 @@ module Clockwork
|
|
|
135
168
|
end
|
|
136
169
|
|
|
137
170
|
to_run.each do |event|
|
|
138
|
-
log "Triggering #{event}"
|
|
171
|
+
log "Triggering '#{event}'"
|
|
139
172
|
event.run(t)
|
|
140
173
|
end
|
|
141
174
|
|
|
@@ -145,6 +178,7 @@ module Clockwork
|
|
|
145
178
|
def clear!
|
|
146
179
|
@@events = []
|
|
147
180
|
@@handler = nil
|
|
181
|
+
@@configuration = Clockwork.default_configuration
|
|
148
182
|
end
|
|
149
183
|
|
|
150
184
|
private
|
data/test/clockwork_test.rb
CHANGED
|
@@ -169,4 +169,78 @@ class ClockworkTest < Test::Unit::TestCase
|
|
|
169
169
|
Clockwork.tick(t = Time.now)
|
|
170
170
|
assert_equal t, event.last
|
|
171
171
|
end
|
|
172
|
+
|
|
173
|
+
test "should be configurable" do
|
|
174
|
+
Clockwork.configure do |config|
|
|
175
|
+
config[:sleep_timeout] = 200
|
|
176
|
+
config[:logger] = "A Logger"
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
assert_equal 200, Clockwork.config[:sleep_timeout]
|
|
180
|
+
assert_equal "A Logger", Clockwork.config[:logger]
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
test "configuration should have reasonable defaults" do
|
|
184
|
+
assert_equal 1, Clockwork.config[:sleep_timeout]
|
|
185
|
+
assert Clockwork.config[:logger].is_a?(Logger)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
test "should be able to specify a different timezone than local" do
|
|
189
|
+
Clockwork.every(1.day, 'myjob', :at => '10:00', :tz => 'UTC')
|
|
190
|
+
|
|
191
|
+
assert_wont_run 'jan 1 2010 10:00:00 EST'
|
|
192
|
+
assert_will_run 'jan 1 2010 10:00:00 UTC'
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
test "should be able to specify a different timezone than local for multiple times" do
|
|
196
|
+
Clockwork.every(1.day, 'myjob', :at => ['10:00', '8:00'], :tz => 'UTC')
|
|
197
|
+
|
|
198
|
+
assert_wont_run 'jan 1 2010 08:00:00 EST'
|
|
199
|
+
assert_will_run 'jan 1 2010 08:00:00 UTC'
|
|
200
|
+
assert_wont_run 'jan 1 2010 10:00:00 EST'
|
|
201
|
+
assert_will_run 'jan 1 2010 10:00:00 UTC'
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
test "should be able to configure a default timezone to use for all events" do
|
|
205
|
+
Clockwork.configure { |config| config[:tz] = 'UTC' }
|
|
206
|
+
Clockwork.every(1.day, 'myjob', :at => '10:00')
|
|
207
|
+
|
|
208
|
+
assert_wont_run 'jan 1 2010 10:00:00 EST'
|
|
209
|
+
assert_will_run 'jan 1 2010 10:00:00 UTC'
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
test "should be able to override a default timezone in an event" do
|
|
213
|
+
Clockwork.configure { |config| config[:tz] = 'UTC' }
|
|
214
|
+
Clockwork.every(1.day, 'myjob', :at => '10:00', :tz => 'EST')
|
|
215
|
+
|
|
216
|
+
assert_will_run 'jan 1 2010 10:00:00 EST'
|
|
217
|
+
assert_wont_run 'jan 1 2010 10:00:00 UTC'
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
test ":if true then always run" do
|
|
221
|
+
Clockwork.every(1.second, 'myjob', :if => lambda { |_| true })
|
|
222
|
+
|
|
223
|
+
assert_will_run 'jan 1 2010 16:20:00'
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
test ":if false then never run" do
|
|
227
|
+
Clockwork.every(1.second, 'myjob', :if => lambda { |_| false })
|
|
228
|
+
|
|
229
|
+
assert_wont_run 'jan 1 2010 16:20:00'
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
test ":if the first day of month" do
|
|
233
|
+
Clockwork.every(1.second, 'myjob', :if => lambda { |t| t.day == 1 })
|
|
234
|
+
|
|
235
|
+
assert_will_run 'jan 1 2010 16:20:00'
|
|
236
|
+
assert_wont_run 'jan 2 2010 16:20:00'
|
|
237
|
+
assert_will_run 'feb 1 2010 16:20:00'
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
test ":if is not callable then raise ArgumentError" do
|
|
241
|
+
assert_raise(ArgumentError) do
|
|
242
|
+
Clockwork.every(1.second, 'myjob', :if => true)
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
172
246
|
end
|
metadata
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: clockwork
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease:
|
|
5
|
-
version: 0.
|
|
5
|
+
version: 0.4.0
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
8
8
|
- Adam Wiggins
|
|
@@ -10,21 +10,21 @@ autorequire:
|
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
12
|
|
|
13
|
-
date:
|
|
13
|
+
date: 2012-03-31 00:00:00 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
|
-
name:
|
|
16
|
+
name: tzinfo
|
|
17
17
|
requirement: &id001 !ruby/object:Gem::Requirement
|
|
18
18
|
none: false
|
|
19
19
|
requirements:
|
|
20
20
|
- - ">="
|
|
21
21
|
- !ruby/object:Gem::Version
|
|
22
22
|
version: "0"
|
|
23
|
-
type: :
|
|
23
|
+
type: :runtime
|
|
24
24
|
prerelease: false
|
|
25
25
|
version_requirements: *id001
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
|
-
name:
|
|
27
|
+
name: jeweler
|
|
28
28
|
requirement: &id002 !ruby/object:Gem::Requirement
|
|
29
29
|
none: false
|
|
30
30
|
requirements:
|
|
@@ -35,7 +35,7 @@ dependencies:
|
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: *id002
|
|
37
37
|
- !ruby/object:Gem::Dependency
|
|
38
|
-
name:
|
|
38
|
+
name: contest
|
|
39
39
|
requirement: &id003 !ruby/object:Gem::Requirement
|
|
40
40
|
none: false
|
|
41
41
|
requirements:
|
|
@@ -45,6 +45,17 @@ dependencies:
|
|
|
45
45
|
type: :development
|
|
46
46
|
prerelease: false
|
|
47
47
|
version_requirements: *id003
|
|
48
|
+
- !ruby/object:Gem::Dependency
|
|
49
|
+
name: mocha
|
|
50
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
|
51
|
+
none: false
|
|
52
|
+
requirements:
|
|
53
|
+
- - ">="
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: "0"
|
|
56
|
+
type: :development
|
|
57
|
+
prerelease: false
|
|
58
|
+
version_requirements: *id004
|
|
48
59
|
description: A scheduler process to replace cron, using a more flexible Ruby syntax running as a single long-running process. Inspired by rufus-scheduler and resque-scheduler.
|
|
49
60
|
email: adam@heroku.com
|
|
50
61
|
executables:
|
|
@@ -75,6 +86,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
75
86
|
requirements:
|
|
76
87
|
- - ">="
|
|
77
88
|
- !ruby/object:Gem::Version
|
|
89
|
+
hash: -383118451
|
|
90
|
+
segments:
|
|
91
|
+
- 0
|
|
78
92
|
version: "0"
|
|
79
93
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
94
|
none: false
|
|
@@ -85,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
85
99
|
requirements: []
|
|
86
100
|
|
|
87
101
|
rubyforge_project: clockwork
|
|
88
|
-
rubygems_version: 1.8.
|
|
102
|
+
rubygems_version: 1.8.17
|
|
89
103
|
signing_key:
|
|
90
104
|
specification_version: 3
|
|
91
105
|
summary: A scheduler process to replace cron.
|