beanstalker 0.4.5 → 0.4.6

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/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