clockwork 0.5.4 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -16,51 +16,63 @@ Quickstart
16
16
 
17
17
  Create clock.rb:
18
18
 
19
- require 'clockwork'
20
- include Clockwork
19
+ ```ruby
20
+ require 'clockwork'
21
+ include Clockwork
21
22
 
22
- handler do |job|
23
- puts "Running #{job}"
24
- end
23
+ handler do |job|
24
+ puts "Running #{job}"
25
+ end
25
26
 
26
- every(10.seconds, 'frequent.job')
27
- every(3.minutes, 'less.frequent.job')
28
- every(1.hour, 'hourly.job')
27
+ every(10.seconds, 'frequent.job')
28
+ every(3.minutes, 'less.frequent.job')
29
+ every(1.hour, 'hourly.job')
29
30
 
30
- every(1.day, 'midnight.job', :at => '00:00')
31
+ every(1.day, 'midnight.job', :at => '00:00')
32
+ ```
31
33
 
32
34
  Run it with the clockwork binary:
33
35
 
34
- $ clockwork clock.rb
35
- Starting clock for 4 events: [ frequent.job less.frequent.job hourly.job midnight.job ]
36
- Triggering frequent.job
36
+ ```
37
+ $ clockwork clock.rb
38
+ Starting clock for 4 events: [ frequent.job less.frequent.job hourly.job midnight.job ]
39
+ Triggering frequent.job
40
+ ```
37
41
 
38
42
  If you would not like to taint the namespace with `include Clockwork`, you can use
39
43
  it as the module (thanks to [hoverlover](https://github.com/hoverlover/clockwork/)).
40
44
 
41
- require 'clockwork'
45
+ As reported in [issue #41](https://github.com/tomykaira/clockwork/issues/41#issuecomment-22073609),
46
+ this technique is necessary when you use Clockwork with Sinatra,
47
+ because both Sinatra and Clockwork add `register()` method into global namespace.
42
48
 
43
- module Clockwork
49
+ ```ruby
50
+ require 'clockwork'
44
51
 
45
- configure do |config|
46
- config[:tz] = "America/Chicago"
47
- end
52
+ module Clockwork
48
53
 
49
- handler do |job|
50
- puts "Running #{job}"
51
- end
54
+ configure do |config|
55
+ config[:tz] = "America/Chicago"
56
+ end
52
57
 
53
- every(10.seconds, 'frequent.job')
54
- every(3.minutes, 'less.frequent.job')
55
- every(1.hour, 'hourly.job')
58
+ handler do |job|
59
+ puts "Running #{job}"
60
+ end
56
61
 
57
- every(1.day, 'midnight.job', :at => '00:00')
58
- end
62
+ every(10.seconds, 'frequent.job')
63
+ every(3.minutes, 'less.frequent.job')
64
+ every(1.hour, 'hourly.job')
65
+
66
+ every(1.day, 'midnight.job', :at => '00:00')
67
+ end
68
+ ```
59
69
 
60
70
  If you need to load your entire environment for your jobs, simply add:
61
71
 
62
- require './config/boot'
63
- require './config/environment'
72
+ ```ruby
73
+ require './config/boot'
74
+ require './config/environment'
75
+ ```
64
76
 
65
77
  under the `require 'clockwork'` declaration.
66
78
 
@@ -89,12 +101,14 @@ scalability.
89
101
 
90
102
  For example, if you're using Beanstalk/Staker:
91
103
 
92
- require 'stalker'
104
+ ```ruby
105
+ require 'stalker'
93
106
 
94
- handler { |job| Stalker.enqueue(job) }
107
+ handler { |job| Stalker.enqueue(job) }
95
108
 
96
- every(1.hour, 'feeds.refresh')
97
- every(1.day, 'reminders.send', :at => '01:30')
109
+ every(1.hour, 'feeds.refresh')
110
+ every(1.day, 'reminders.send', :at => '01:30')
111
+ ```
98
112
 
99
113
  Using a queueing system which doesn't require that your full application be
100
114
  loaded is preferable, because the clock process can keep a tiny memory
@@ -102,11 +116,13 @@ footprint. If you're using DJ or Resque, however, you can go ahead and load
102
116
  your full application enviroment, and use per-event blocks to call DJ or Resque
103
117
  enqueue methods. For example, with DJ/Rails:
104
118
 
105
- require 'config/boot'
106
- require 'config/environment'
119
+ ```ruby
120
+ require 'config/boot'
121
+ require 'config/environment'
107
122
 
108
- every(1.hour, 'feeds.refresh') { Feed.send_later(:refresh) }
109
- every(1.day, 'reminders.send', :at => '01:30') { Reminder.send_later(:send_reminders) }
123
+ every(1.hour, 'feeds.refresh') { Feed.send_later(:refresh) }
124
+ every(1.day, 'reminders.send', :at => '01:30') { Reminder.send_later(:send_reminders) }
125
+ ```
110
126
 
111
127
  Parameters
112
128
  ----------
@@ -117,26 +133,36 @@ Parameters
117
133
 
118
134
  The simplest example:
119
135
 
120
- every(1.day, 'reminders.send', :at => '01:30')
136
+ ```ruby
137
+ every(1.day, 'reminders.send', :at => '01:30')
138
+ ```
121
139
 
122
140
  You can omit 0 of the hour:
123
141
 
124
- every(1.day, 'reminders.send', :at => '1:30')
142
+ ```ruby
143
+ every(1.day, 'reminders.send', :at => '1:30')
144
+ ```
125
145
 
126
146
  The wildcard for hour is supported:
127
147
 
128
- every(1.hour, 'reminders.send', :at => '**:30')
148
+ ```ruby
149
+ every(1.hour, 'reminders.send', :at => '**:30')
150
+ ```
129
151
 
130
152
  You can set more than one timing:
131
153
 
132
- every(1.hour, 'reminders.send', :at => ['12:00', '18:00'])
133
- # send reminders at noon and evening
154
+ ```ruby
155
+ every(1.hour, 'reminders.send', :at => ['12:00', '18:00'])
156
+ # send reminders at noon and evening
157
+ ```
134
158
 
135
159
  You can also specify a timezone (default is the local timezone):
136
160
 
137
- every(1.day, 'reminders.send', :at => '00:00', :tz => 'UTC')
138
- # Runs the job each day at midnight, UTC.
139
- # The value for :tz can be anything supported by [TZInfo](http://tzinfo.rubyforge.org/)
161
+ ```ruby
162
+ every(1.day, 'reminders.send', :at => '00:00', :tz => 'UTC')
163
+ # Runs the job each day at midnight, UTC.
164
+ # The value for :tz can be anything supported by [TZInfo](http://tzinfo.rubyforge.org/)
165
+ ```
140
166
 
141
167
  ### :if
142
168
 
@@ -145,14 +171,17 @@ return value is true.
145
171
 
146
172
  Run on every first day of month.
147
173
 
148
- Clockwork.every(1.day, 'myjob', :if => lambda { |t| t.day == 1 })
174
+ ```ruby
175
+ Clockwork.every(1.day, 'myjob', :if => lambda { |t| t.day == 1 })
176
+ ```
149
177
 
150
178
  The argument is an instance of `ActiveSupport::TimeWithZone` if the `:tz` option is set. Otherwise, it's an instance of `Time`.
151
179
 
152
180
  This argument cannot be omitted. Please use _ as placeholder if not needed.
153
181
 
154
- Clockwork.every(1.second, 'myjob', :if => lambda { |_| true })
155
-
182
+ ```ruby
183
+ Clockwork.every(1.second, 'myjob', :if => lambda { |_| true })
184
+ ```
156
185
 
157
186
  ### :thread
158
187
 
@@ -188,12 +217,14 @@ jobs.
188
217
 
189
218
  ### Configuration example
190
219
 
191
- Clockwork.configure do |config|
192
- config[:sleep_timeout] = 5
193
- config[:logger] = Logger.new(log_file_path)
194
- config[:tz] = 'EST'
195
- config[:max_threads] = 15
196
- end
220
+ ```ruby
221
+ Clockwork.configure do |config|
222
+ config[:sleep_timeout] = 5
223
+ config[:logger] = Logger.new(log_file_path)
224
+ config[:tz] = 'EST'
225
+ config[:max_threads] = 15
226
+ end
227
+ ```
197
228
 
198
229
  Anatomy of a clock file
199
230
  -----------------------
@@ -205,7 +236,9 @@ and then the events themselves.
205
236
 
206
237
  The handler typically looks like this:
207
238
 
208
- handler { |job| enqueue_your_job(job) }
239
+ ```ruby
240
+ handler { |job| enqueue_your_job(job) }
241
+ ```
209
242
 
210
243
  This block will be invoked every time an event is triggered, with the job name
211
244
  passed in. In most cases, you should be able to pass the job name directly
@@ -213,8 +246,10 @@ through to your queueing system.
213
246
 
214
247
  The second part of the file are the events, which roughly resembles a crontab:
215
248
 
216
- every(5.minutes, 'thing.do')
217
- every(1.hour, 'otherthing.do')
249
+ ```ruby
250
+ every(5.minutes, 'thing.do')
251
+ every(1.hour, 'otherthing.do')
252
+ ```
218
253
 
219
254
  In the first line of this example, an event will be triggered once every five
220
255
  minutes, passing the job name 'thing.do' into the handler. The handler shown
@@ -225,16 +260,20 @@ rely on classes rather than job names (i.e. DJ and Resque). In this case, you
225
260
  need not define a general event handler, and instead provide one with each
226
261
  event:
227
262
 
228
- every(5.minutes, 'thing.do') { Thing.send_later(:do) }
263
+ ```ruby
264
+ every(5.minutes, 'thing.do') { Thing.send_later(:do) }
265
+ ```
229
266
 
230
267
  If you provide a custom handler for the block, the job name is used only for
231
268
  logging.
232
269
 
233
270
  You can also use blocks to do more complex checks:
234
271
 
235
- every(1.day, 'check.leap.year') do
236
- Stalker.enqueue('leap.year.party') if Time.now.year % 4 == 0
237
- end
272
+ ```ruby
273
+ every(1.day, 'check.leap.year') do
274
+ Stalker.enqueue('leap.year.party') if Time.now.year % 4 == 0
275
+ end
276
+ ```
238
277
 
239
278
  In production
240
279
  -------------
@@ -259,7 +298,9 @@ You need `daemons` gem to use `clockworkd`. It is not automatically installed,
259
298
 
260
299
  Then,
261
300
 
262
- clockworkd -c YOUR_CLOCK.rb start
301
+ ```
302
+ clockworkd -c YOUR_CLOCK.rb start
303
+ ```
263
304
 
264
305
  For more details, see help shown by `clockworkd`.
265
306
 
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
2
 
3
3
  task 'test' do
4
- sh "ruby test/clockwork_test.rb"
4
+ sh 'ruby test/clockwork_test.rb'
5
5
  end
6
6
 
7
7
  task :default => :test
@@ -4,7 +4,7 @@ STDERR.sync = STDOUT.sync = true
4
4
 
5
5
  require 'clockwork'
6
6
 
7
- usage = "clockwork <clock.rb>"
7
+ usage = 'clockwork <clock.rb>'
8
8
  file = ARGV.shift or abort usage
9
9
 
10
10
  file = "./#{file}" unless file.match(/^[\/.]/)
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "clockwork"
3
- s.version = "0.5.4"
3
+ s.version = "0.5.5"
4
4
 
5
5
  s.authors = ["Adam Wiggins", "tomykaira"]
6
6
  s.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."
data/example.rb CHANGED
@@ -12,5 +12,5 @@ every(1.hour, 'run.me.every.hour')
12
12
  every(1.day, 'run.me.at.midnight', :at => '00:00')
13
13
 
14
14
  every(1.day, 'custom.event.handler', :at => '00:30') do
15
- puts "This event has its own handler"
15
+ puts 'This event has its own handler'
16
16
  end
@@ -17,7 +17,7 @@ module Clockwork
17
17
  case at
18
18
  when /^([[:alpha:]]+)\s(.*)$/
19
19
  ret = parse($2)
20
- wday = WDAYS.find_index {|x| x.include?($1) }
20
+ wday = WDAYS.find_index { |x| x.include?($1) }
21
21
  raise FailedToParse, at if wday.nil?
22
22
  ret.wday = wday
23
23
  ret
@@ -69,9 +69,7 @@ module Clockwork
69
69
  end
70
70
  end
71
71
 
72
- if options[:thread]
73
- @thread = options[:thread]
74
- end
72
+ @thread = !!(options.has_key?(:thread) ? options[:thread] : Clockwork.config[:thread])
75
73
 
76
74
  @timezone = options[:tz] || Clockwork.config[:tz]
77
75
  end
@@ -94,16 +92,12 @@ module Clockwork
94
92
  @thread
95
93
  end
96
94
 
97
- def thread_available?
98
- Thread.list.count < Clockwork.config[:max_threads]
99
- end
100
-
101
95
  def run(t)
102
96
  t = convert_timezone(t)
103
97
  @last = t
104
98
 
105
99
  if thread?
106
- if thread_available?
100
+ if Clockwork.thread_available?
107
101
  Thread.new { execute }
108
102
  else
109
103
  log_error "Threads exhausted; skipping #{self}"
@@ -135,6 +129,10 @@ module Clockwork
135
129
  end
136
130
  end
137
131
 
132
+ def thread_available?
133
+ Thread.list.count < config[:max_threads]
134
+ end
135
+
138
136
  def configure
139
137
  yield(config)
140
138
  end
@@ -146,7 +144,7 @@ module Clockwork
146
144
  extend self
147
145
 
148
146
  def default_configuration
149
- { :sleep_timeout => 1, :logger => Logger.new(STDOUT), :max_threads => 10 }
147
+ { :sleep_timeout => 1, :logger => Logger.new(STDOUT), :thread => false, :max_threads => 10 }
150
148
  end
151
149
 
152
150
  @@configuration = default_configuration
@@ -180,17 +180,20 @@ class ClockworkTest < Test::Unit::TestCase
180
180
  config[:sleep_timeout] = 200
181
181
  config[:logger] = "A Logger"
182
182
  config[:max_threads] = 10
183
+ config[:thread] = true
183
184
  end
184
185
 
185
186
  assert_equal 200, Clockwork.config[:sleep_timeout]
186
187
  assert_equal "A Logger", Clockwork.config[:logger]
187
188
  assert_equal 10, Clockwork.config[:max_threads]
189
+ assert_equal true, Clockwork.config[:thread]
188
190
  end
189
191
 
190
192
  test "configuration should have reasonable defaults" do
191
193
  assert_equal 1, Clockwork.config[:sleep_timeout]
192
194
  assert Clockwork.config[:logger].is_a?(Logger)
193
195
  assert_equal 10, Clockwork.config[:max_threads]
196
+ assert_equal false, Clockwork.config[:thread]
194
197
  end
195
198
 
196
199
  test "should be able to specify a different timezone than local" do
@@ -246,7 +249,7 @@ class ClockworkTest < Test::Unit::TestCase
246
249
  end
247
250
 
248
251
  test ":if it is compared to a time with zone" do
249
- tz = "America/Chicago"
252
+ tz = 'America/Chicago'
250
253
  time = Time.utc(2012,5,25,10,00)
251
254
  Clockwork.every(1.second, 'myjob', tz: tz, :if => lambda { |t|(
252
255
  ((time - 1.hour)..(time + 1.hour)).cover? t
@@ -271,4 +274,34 @@ class ClockworkTest < Test::Unit::TestCase
271
274
  Clockwork.tick(Time.now)
272
275
  end
273
276
 
277
+ describe "thread option" do
278
+ test "should not use thread by default" do
279
+ event = Clockwork.every(1.minute, 'myjob')
280
+ assert !event.thread?
281
+ end
282
+
283
+ test "should use thread if thread option is specified with truly value" do
284
+ event = Clockwork.every(1.minute, 'myjob', :thread => true)
285
+ assert event.thread?
286
+ end
287
+
288
+ test "should use thread if global thread option is set" do
289
+ Clockwork.configure do |config|
290
+ config[:thread] = true
291
+ end
292
+
293
+ event = Clockwork.every(1.minute, 'myjob')
294
+ assert event.thread?
295
+ end
296
+
297
+ test "should not use thread if job option overrides global option" do
298
+ Clockwork.configure do |config|
299
+ config[:thread] = true
300
+ end
301
+
302
+ event = Clockwork.every(1.minute, 'myjob', :thread => false)
303
+ assert !event.thread?
304
+ end
305
+ end
306
+
274
307
  end
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.5.4
4
+ version: 0.5.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-07-24 00:00:00.000000000 Z
13
+ date: 2013-08-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: tzinfo
@@ -163,7 +163,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
163
163
  version: '0'
164
164
  segments:
165
165
  - 0
166
- hash: 437114255
166
+ hash: -871026735
167
167
  required_rubygems_version: !ruby/object:Gem::Requirement
168
168
  none: false
169
169
  requirements:
@@ -172,7 +172,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
172
172
  version: '0'
173
173
  segments:
174
174
  - 0
175
- hash: 437114255
175
+ hash: -871026735
176
176
  requirements: []
177
177
  rubyforge_project:
178
178
  rubygems_version: 1.8.23