beanstalker 0.4.5 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.5
1
+ 0.4.6
data/beanstalker.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{beanstalker}
8
- s.version = "0.4.5"
8
+ s.version = "0.4.6"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Gleb Pomykalov"]
12
- s.date = %q{2010-07-21}
12
+ s.date = %q{2010-07-29}
13
13
  s.description = %q{Beanstalker is a tool for executing long tasks in background in our rails application.}
14
14
  s.email = %q{glebpom@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -14,11 +14,15 @@ module Beanstalker
14
14
  if option(:error_handler)
15
15
  Worker.custom_error_handler = option(:error_handler)
16
16
  end
17
+ if option(:timeout_handler)
18
+ Worker.custom_timeout_handler = option(:timeout_handler)
19
+ end
17
20
  @worker = Worker.new(binding,
18
21
  :tube => option(:tube),
19
22
  :servers => option(:servers),
20
23
  :worker_id => worker_id,
21
- :workers_count => workers_count)
24
+ :workers_count => workers_count,
25
+ :ruby_timeout => option(:ruby_timeout).nil? ? true : option(:ruby_timeout))
22
26
  @worker.run
23
27
  $logger.info "Ending cycle"
24
28
  end
@@ -77,7 +77,7 @@ class << Beanstalker::Queue
77
77
  packed = pkg(code, worker_opts, obj, sel)
78
78
  end
79
79
 
80
- RAILS_DEFAULT_LOGGER.info("put #{pri} #{code} to #{tube}")
80
+ RAILS_DEFAULT_LOGGER.info("put #{pri} #{code} to #{tube} with ttr #{ttr}")
81
81
  put!(packed, pri, delay, ttr, tube)
82
82
  end
83
83
 
@@ -26,12 +26,17 @@ class Beanstalker::Worker
26
26
  class << self
27
27
  attr_accessor :finish
28
28
  attr_accessor :custom_error_handler
29
+ attr_accessor :custom_timeout_handler
29
30
  attr_accessor :before_filter
30
31
 
31
32
  def error_handler(&block)
32
33
  self.custom_error_handler = block
33
34
  end
34
35
 
36
+ def timeout_handler(&block)
37
+ self.custom_timeout_handler = block
38
+ end
39
+
35
40
  def before_reserves
36
41
  @before_reserves ||= []
37
42
  end
@@ -45,10 +50,6 @@ class Beanstalker::Worker
45
50
  end
46
51
  end
47
52
 
48
- def logger
49
- $logger or RAILS_DEFAULT_LOGGER
50
- end
51
-
52
53
  def initialize(top_binding, options = {})
53
54
  @top_binding = top_binding
54
55
  @stop = false
@@ -77,7 +78,7 @@ class Beanstalker::Worker
77
78
  to_ignore.each do |t|
78
79
  Beanstalker::Queue.queue.ignore(t)
79
80
  end
80
- logger.info "Using tubes: #{Beanstalker::Queue.queue.list_tubes_watched.values.flatten.join(',')}"
81
+ Daemonizer.logger.info "Using tubes: #{Beanstalker::Queue.queue.list_tubes_watched.values.flatten.join(',')}"
81
82
  Daemonizer.flush_logger
82
83
  end
83
84
 
@@ -125,13 +126,13 @@ class Beanstalker::Worker
125
126
  rescue Beanstalk::DeadlineSoonError
126
127
  # Do nothing; immediately try again, giving the user a chance to
127
128
  # clean up in the before_reserve hook.
128
- logger.info 'Job deadline soon; you should clean up.'
129
+ Daemonizer.logger.info 'Job deadline soon; you should clean up.'
129
130
  rescue Exception => ex
130
131
  @q_hint = nil # in case there's something wrong with this conn
131
- logger.info(
132
+ Daemonizer.logger.info(
132
133
  "#{ex.class}: #{ex}\n" + ex.backtrace.join("\n"))
133
- logger.info 'something is wrong. We failed to get a job.'
134
- logger.info "sleeping for #{SLEEP_TIME}s..."
134
+ Daemonizer.logger.info 'something is wrong. We failed to get a job.'
135
+ Daemonizer.logger.info "sleeping for #{SLEEP_TIME}s..."
135
136
  sleep(SLEEP_TIME)
136
137
  end
137
138
  end
@@ -145,6 +146,8 @@ class Beanstalker::Worker
145
146
  def safe_dispatch(job)
146
147
  begin
147
148
  return dispatch(job)
149
+ rescue Timeout::Error
150
+ handle_timeout(job)
148
151
  rescue Interrupt => ex
149
152
  begin job.release rescue :ok end
150
153
  raise ex
@@ -163,20 +166,47 @@ class Beanstalker::Worker
163
166
  end
164
167
  end
165
168
 
169
+ def handle_timeout(job)
170
+ if self.class.custom_timeout_handler
171
+ self.class.custom_timeout_handler.call(job)
172
+ else
173
+ self.class.default_handle_timeout(job)
174
+ end
175
+ end
176
+
166
177
  def self.default_handle_error(job, ex)
167
- logger.info "Job failed: #{job.server}/#{job.id}"
168
- logger.info("#{ex.class}: #{ex}\n" + ex.backtrace.join("\n"))
178
+ Daemonizer.logger.info "Job failed: #{job.server}/#{job.id}"
179
+ Daemonizer.logger.info("#{ex.class}: #{ex}\n" + ex.backtrace.join("\n"))
180
+ job.decay
181
+ rescue Beanstalk::UnexpectedResponse => e
182
+ Daemonizer.logger.info "Unexpected Beanstalkd error: #{job.server}/#{job.id}. #{e.inspect}"
183
+ end
184
+
185
+ def self.default_handle_timeout(job)
186
+ Daemonizer.logger.info "Job timeout: #{job.server}/#{job.id}"
169
187
  job.decay
170
- rescue Beanstalk::UnexpectedResponse
188
+ rescue Beanstalk::UnexpectedResponse => e
189
+ Daemonizer.logger.info "Unexpected Beanstalkd error: #{job.server}/#{job.id}. #{e.inspect}"
171
190
  end
172
191
 
173
192
  def run_ao_job(job)
174
- logger.info "Running '#{job[:code]}'. Age #{job.stats['age']}, Releases #{job.stats['releases']}"
175
- f = self.class.before_filter
176
- result = f.call(job) if f
177
- run_code(job)
178
- job.delete
179
- logger.info "Finished"
193
+ runner = lambda {
194
+ f = self.class.before_filter
195
+ result = f.call(job) if f
196
+ run_code(job)
197
+ job.delete
198
+ }
199
+ if @options[:ruby_timeout]
200
+ timeout = (job.stats['ttr'].to_f * 0.8)
201
+ Daemonizer.logger.info "TO=#{timeout} sec. Job id=#{job.stats['id']}. Running '#{job[:code]}'. Age #{job.stats['age']}, Releases #{job.stats['releases']}, TTR #{job.stats['ttr']}"
202
+ Timeout.timeout(timeout) do
203
+ runner.call
204
+ end
205
+ else
206
+ Daemonizer.logger.info "Job id=#{job.stats['id']}. Running '#{job[:code]}'. Age #{job.stats['age']}, Releases #{job.stats['releases']}, TTR #{job.stats['ttr']}"
207
+ runner.call
208
+ end
209
+ Daemonizer.logger.info "Finished"
180
210
  end
181
211
 
182
212
  def run_code(job)
@@ -188,7 +218,7 @@ class Beanstalker::Worker
188
218
  end
189
219
 
190
220
  def do_all_work
191
- logger.info 'finishing all running jobs'
221
+ Daemonizer.logger.info 'finishing all running jobs'
192
222
  f = self.class.finish
193
223
  f.call if f
194
224
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beanstalker
3
3
  version: !ruby/object:Gem::Version
4
- hash: 5
4
+ hash: 3
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
- - 5
10
- version: 0.4.5
9
+ - 6
10
+ version: 0.4.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - Gleb Pomykalov
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-07-21 00:00:00 +04:00
18
+ date: 2010-07-29 00:00:00 +04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency