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 +1 -1
- data/beanstalker.gemspec +2 -2
- data/lib/beanstalker/daemonizer_handler.rb +5 -1
- data/lib/beanstalker/queue.rb +1 -1
- data/lib/beanstalker/worker.rb +49 -19
- metadata +4 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
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.
|
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-
|
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
|
data/lib/beanstalker/queue.rb
CHANGED
@@ -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
|
|
data/lib/beanstalker/worker.rb
CHANGED
@@ -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
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
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:
|
4
|
+
hash: 3
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 4
|
9
|
-
-
|
10
|
-
version: 0.4.
|
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-
|
18
|
+
date: 2010-07-29 00:00:00 +04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|