clockwork 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,5 +1,7 @@
1
1
  source :rubygems
2
2
 
3
+ gem 'tzinfo'
4
+
3
5
  group :development, :test do
4
6
  gem 'jeweler'
5
7
  gem 'contest'
@@ -11,6 +11,7 @@ GEM
11
11
  mocha (0.10.0)
12
12
  metaclass (~> 0.0.1)
13
13
  rake (0.9.2)
14
+ tzinfo (0.3.32)
14
15
 
15
16
  PLATFORMS
16
17
  ruby
@@ -19,3 +20,4 @@ DEPENDENCIES
19
20
  contest
20
21
  jeweler
21
22
  mocha
23
+ tzinfo
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.3.4
1
+ 0.4.0
@@ -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
- ellapsed_ready = (@last.nil? or (t - @last).to_i >= @period)
69
- ellapsed_ready and (@at.nil? or @at.ready?(t))
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
- STDERR.puts exception_message(e)
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 1
157
+ sleep(config[:sleep_timeout])
125
158
  end
126
159
  end
127
160
 
128
161
  def log(msg)
129
- puts msg
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
@@ -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.3.4
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: 2011-12-14 00:00:00 Z
13
+ date: 2012-03-31 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
- name: jeweler
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: :development
23
+ type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: *id001
26
26
  - !ruby/object:Gem::Dependency
27
- name: contest
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: mocha
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.6
102
+ rubygems_version: 1.8.17
89
103
  signing_key:
90
104
  specification_version: 3
91
105
  summary: A scheduler process to replace cron.