quebert 0.0.8 → 0.0.9
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/.gitignore +22 -0
- data/Gemfile +8 -7
- data/Guardfile +8 -0
- data/Rakefile +1 -44
- data/lib/quebert/backend/beanstalk.rb +3 -0
- data/lib/quebert/configuration.rb +10 -2
- data/lib/quebert/controller/beanstalk.rb +50 -5
- data/lib/quebert/job.rb +12 -4
- data/lib/quebert/logging.rb +15 -0
- data/lib/quebert/support.rb +1 -1
- data/lib/quebert/version.rb +3 -0
- data/lib/quebert/worker.rb +5 -19
- data/lib/quebert.rb +3 -0
- data/quebert.gemspec +21 -104
- data/spec/consumer_spec.rb +25 -0
- data/spec/job_spec.rb +9 -2
- data/spec/support/jobs.rb +13 -0
- metadata +37 -45
- data/VERSION +0 -1
data/.gitignore
ADDED
data/Gemfile
CHANGED
@@ -1,13 +1,14 @@
|
|
1
|
-
source
|
1
|
+
source "http://rubygems.org"
|
2
2
|
|
3
|
-
gem
|
4
|
-
|
3
|
+
# Specify your gem's dependencies in quebert.gemspec
|
4
|
+
gemspec
|
5
5
|
|
6
|
+
# TODO - update this to Guard and move into the gemspec dev dependencies
|
6
7
|
group :test do
|
7
|
-
gem 'rspec', '1.3.0', :require => nil
|
8
|
-
gem 'ZenTest'
|
9
8
|
gem 'ruby-debug'
|
10
|
-
gem 'activerecord',
|
9
|
+
gem 'activerecord', '2.3.5'
|
11
10
|
gem 'sqlite3-ruby'
|
12
|
-
gem '
|
11
|
+
gem 'guard-rspec'
|
12
|
+
gem 'rb-fsevent'
|
13
|
+
gem 'growl'
|
13
14
|
end
|
data/Guardfile
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec', :version => 1, :cli => '--colour --format nested' do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
end
|
data/Rakefile
CHANGED
@@ -1,44 +1 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
begin
|
4
|
-
require 'jeweler'
|
5
|
-
Jeweler::Tasks.new do |gem|
|
6
|
-
gem.name = "quebert"
|
7
|
-
gem.summary = %Q{A worker queue framework built around beanstalkd}
|
8
|
-
gem.description = %Q{A worker queue framework built around beanstalkd}
|
9
|
-
gem.email = "brad@bradgessler.com"
|
10
|
-
gem.homepage = "http://github.com/bradgessler/quebert"
|
11
|
-
gem.authors = ["Brad Gessler"]
|
12
|
-
gem.add_development_dependency "rspec", ">= 1.2.9"
|
13
|
-
gem.add_dependency "json"
|
14
|
-
gem.add_dependency "beanstalk-client"
|
15
|
-
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
|
-
end
|
17
|
-
Jeweler::GemcutterTasks.new
|
18
|
-
rescue LoadError
|
19
|
-
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
20
|
-
end
|
21
|
-
|
22
|
-
require 'spec/rake/spectask'
|
23
|
-
Spec::Rake::SpecTask.new(:spec) do |spec|
|
24
|
-
spec.libs << 'lib' << 'spec'
|
25
|
-
spec.spec_files = FileList['spec/**/*_spec.rb']
|
26
|
-
end
|
27
|
-
|
28
|
-
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
29
|
-
spec.libs << 'lib' << 'spec'
|
30
|
-
spec.pattern = 'spec/**/*_spec.rb'
|
31
|
-
spec.rcov = true
|
32
|
-
end
|
33
|
-
|
34
|
-
task :default => :spec
|
35
|
-
|
36
|
-
require 'rake/rdoctask'
|
37
|
-
Rake::RDocTask.new do |rdoc|
|
38
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
39
|
-
|
40
|
-
rdoc.rdoc_dir = 'rdoc'
|
41
|
-
rdoc.title = "quebert #{version}"
|
42
|
-
rdoc.rdoc_files.include('README*')
|
43
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
44
|
-
end
|
1
|
+
require "bundler/gem_tasks"
|
@@ -20,6 +20,9 @@ module Quebert
|
|
20
20
|
while peek_ready do
|
21
21
|
reserve_without_controller.delete
|
22
22
|
end
|
23
|
+
while peek_delayed do
|
24
|
+
reserve_without_controller.delete
|
25
|
+
end
|
23
26
|
while job = peek_buried do
|
24
27
|
last_conn.kick 1 # what? Why the 1? it kicks them all?
|
25
28
|
reserve_without_controller.delete
|
@@ -5,11 +5,19 @@ module Quebert
|
|
5
5
|
attr_accessor :backend, :logger, :worker
|
6
6
|
|
7
7
|
def logger
|
8
|
-
@logger ||=
|
8
|
+
@logger ||= begin
|
9
|
+
l = Logger.new($stdout)
|
10
|
+
l.formatter = Logger::Formatter.new
|
11
|
+
l
|
12
|
+
end
|
9
13
|
end
|
10
14
|
|
11
15
|
def log_file_path=(path)
|
12
|
-
self.logger =
|
16
|
+
self.logger = begin
|
17
|
+
l = Logger.new(path)
|
18
|
+
l.formatter = Logger::Formatter.new
|
19
|
+
l
|
20
|
+
end
|
13
21
|
end
|
14
22
|
|
15
23
|
def from_hash(hash)
|
@@ -1,9 +1,17 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
|
1
3
|
module Quebert
|
2
4
|
module Controller
|
3
5
|
# Handle interactions between a job and a Beanstalk queue.
|
4
6
|
class Beanstalk < Base
|
7
|
+
include Logging
|
8
|
+
|
5
9
|
attr_reader :beanstalk_job, :queue, :job
|
6
|
-
|
10
|
+
|
11
|
+
MAX_TIMEOUT_RETRY_DELAY = 300
|
12
|
+
TIMEOUT_RETRY_DELAY_SEED = 2
|
13
|
+
TIMEOUT_RETRY_GROWTH_RATE = 3
|
14
|
+
|
7
15
|
def initialize(beanstalk_job, queue)
|
8
16
|
@beanstalk_job, @queue = beanstalk_job, queue
|
9
17
|
|
@@ -11,32 +19,69 @@ module Quebert
|
|
11
19
|
@job = Job.from_json(beanstalk_job.body)
|
12
20
|
rescue Job::Delete
|
13
21
|
beanstalk_job.delete
|
22
|
+
log "Deleted on initialization", :error
|
14
23
|
rescue Job::Release
|
15
|
-
beanstalk_job.release
|
24
|
+
beanstalk_job.release @job.priority, @job.delay
|
25
|
+
log "Released on initialization with priority: #{@job.priority} and delay: #{@job.delay}", :error
|
16
26
|
rescue Job::Bury
|
17
27
|
beanstalk_job.bury
|
28
|
+
log "Buried on initialization", :error
|
18
29
|
rescue Exception => e
|
19
30
|
beanstalk_job.bury
|
31
|
+
log "Exception caught on initialization. #{e.inspect}", :error
|
20
32
|
raise e
|
21
33
|
end
|
22
34
|
end
|
23
35
|
|
24
36
|
def perform
|
25
37
|
begin
|
26
|
-
|
27
|
-
beanstalk_job.
|
38
|
+
log "Performing with args #{job.args.inspect}"
|
39
|
+
log "Beanstalk Job Stats: #{beanstalk_job.stats.inspect}"
|
40
|
+
|
41
|
+
result = false
|
42
|
+
time = Benchmark.realtime do
|
43
|
+
result = job.perform!
|
44
|
+
beanstalk_job.delete
|
45
|
+
end
|
46
|
+
|
47
|
+
log "Completed in #{(time*1000*1000).to_i/1000.to_f} ms\n"
|
28
48
|
result
|
29
49
|
rescue Job::Delete
|
30
50
|
beanstalk_job.delete
|
51
|
+
log "Deleted", :error
|
31
52
|
rescue Job::Release
|
32
|
-
beanstalk_job.release
|
53
|
+
beanstalk_job.release @job.priority, @job.delay
|
54
|
+
log "Released with priority: #{@job.priority} and delay: #{@job.delay}", :error
|
33
55
|
rescue Job::Bury
|
34
56
|
beanstalk_job.bury
|
57
|
+
log "Burried", :error
|
58
|
+
rescue Job::Timeout => e
|
59
|
+
retry_with_delay
|
60
|
+
raise e
|
35
61
|
rescue Exception => e
|
36
62
|
beanstalk_job.bury
|
63
|
+
log "Exception caught on perform. Job buried. #{e.inspect}", :error
|
37
64
|
raise e
|
38
65
|
end
|
39
66
|
end
|
67
|
+
|
68
|
+
protected
|
69
|
+
def retry_with_delay
|
70
|
+
delay = TIMEOUT_RETRY_DELAY_SEED + TIMEOUT_RETRY_GROWTH_RATE**beanstalk_job.stats["releases"].to_i
|
71
|
+
|
72
|
+
if delay > MAX_TIMEOUT_RETRY_DELAY
|
73
|
+
beanstalk_job.bury
|
74
|
+
log "Max retry delay exceeded. Burrying job."
|
75
|
+
else
|
76
|
+
beanstalk_job.release @job.priority, delay
|
77
|
+
log "TTR exceeded. Releasing with priority: #{@job.priority} and delay: #{delay}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def log(message, level=:info)
|
82
|
+
# Have the job write to the log file so that we catch the details of the job
|
83
|
+
job.send(:log, message, level)
|
84
|
+
end
|
40
85
|
end
|
41
86
|
end
|
42
87
|
end
|
data/lib/quebert/job.rb
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
require 'json'
|
2
|
+
require 'system_timer'
|
2
3
|
|
3
4
|
module Quebert
|
4
5
|
class Job
|
6
|
+
include Logging
|
7
|
+
|
5
8
|
attr_reader :args
|
6
9
|
attr_accessor :priority, :delay, :ttr
|
7
10
|
|
8
11
|
DEFAULT_JOB_PRIORITY = 65536
|
9
12
|
DEFAULT_JOB_DELAY = 0
|
10
|
-
DEFAULT_JOB_TTR =
|
13
|
+
DEFAULT_JOB_TTR = 10
|
11
14
|
|
12
15
|
NotImplemented = Class.new(StandardError)
|
13
16
|
|
@@ -16,7 +19,8 @@ module Quebert
|
|
16
19
|
Bury = Class.new(Action)
|
17
20
|
Delete = Class.new(Action)
|
18
21
|
Release = Class.new(Action)
|
19
|
-
|
22
|
+
Timeout = Class.new(Action)
|
23
|
+
|
20
24
|
def initialize(*args)
|
21
25
|
opts = args.last.is_a?(::Hash) ? args.pop : nil
|
22
26
|
|
@@ -44,7 +48,10 @@ module Quebert
|
|
44
48
|
|
45
49
|
# Runs the perform method that somebody else should be implementing
|
46
50
|
def perform!
|
47
|
-
|
51
|
+
# Honor the timeout and kill the job
|
52
|
+
SystemTimer.timeout_after(@ttr, Job::Timeout) do
|
53
|
+
perform(*args)
|
54
|
+
end
|
48
55
|
end
|
49
56
|
|
50
57
|
def enqueue
|
@@ -64,10 +71,11 @@ module Quebert
|
|
64
71
|
def self.backend=(backend)
|
65
72
|
@backend = backend
|
66
73
|
end
|
74
|
+
|
67
75
|
def self.backend
|
68
76
|
@backend || Quebert.configuration.backend
|
69
77
|
end
|
70
|
-
|
78
|
+
|
71
79
|
protected
|
72
80
|
def delete!
|
73
81
|
raise Delete
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Quebert
|
4
|
+
module Logging
|
5
|
+
protected
|
6
|
+
def logger
|
7
|
+
@logger ||= Quebert.logger
|
8
|
+
end
|
9
|
+
|
10
|
+
# Making logging jobs a tiny bit easier..
|
11
|
+
def log(message, level=:info)
|
12
|
+
logger.send(level, "[##{self.object_id} #{self.class.name}] : #{message}")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/quebert/support.rb
CHANGED
data/lib/quebert/worker.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
require 'logger'
|
2
|
-
|
3
1
|
module Quebert
|
4
2
|
class Worker
|
5
|
-
|
3
|
+
include Logging
|
4
|
+
|
5
|
+
attr_accessor :exception_handler, :backend
|
6
6
|
|
7
7
|
def initialize
|
8
8
|
yield self if block_given?
|
@@ -12,31 +12,22 @@ module Quebert
|
|
12
12
|
def start
|
13
13
|
Signal.trap('TERM'){ stop }
|
14
14
|
|
15
|
-
logger.info "Worker
|
15
|
+
logger.info "Worker started with #{backend.class.name} backend\n"
|
16
16
|
while controller = backend.reserve do
|
17
17
|
begin
|
18
|
-
log controller.job, "performing with args #{controller.job.args.inspect}."
|
19
|
-
log controller.job, "Priority: #{controller.beanstalk_job.pri}, Delay: #{controller.beanstalk_job.delay}, TTR: #{controller.beanstalk_job.ttr}" if controller.respond_to?(:beanstalk_job)
|
20
18
|
controller.perform
|
21
|
-
log controller.job, "complete"
|
22
19
|
rescue Exception => e
|
23
|
-
log controller.job, "fault #{e}", :error
|
24
20
|
exception_handler ? exception_handler.call(e) : raise(e)
|
25
21
|
end
|
26
22
|
end
|
27
23
|
end
|
28
24
|
|
29
25
|
def stop
|
30
|
-
logger.info "Worker
|
26
|
+
logger.info "Worker stopping\n"
|
31
27
|
exit 0
|
32
28
|
end
|
33
29
|
|
34
30
|
protected
|
35
|
-
# Setup a bunch of stuff with Quebert config defaults the we can override later.
|
36
|
-
def logger
|
37
|
-
@logger ||= Quebert.logger
|
38
|
-
end
|
39
|
-
|
40
31
|
def backend
|
41
32
|
@backend ||= Quebert.config.backend
|
42
33
|
end
|
@@ -44,10 +35,5 @@ module Quebert
|
|
44
35
|
def exception_handler
|
45
36
|
@exception_handler ||= Quebert.config.worker.exception_handler
|
46
37
|
end
|
47
|
-
|
48
|
-
# Making logging jobs a tiny bit easier..
|
49
|
-
def log(job, message, level=:info)
|
50
|
-
logger.send(level, "#{job.class.name}##{job.object_id}: #{message}")
|
51
|
-
end
|
52
38
|
end
|
53
39
|
end
|
data/lib/quebert.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'quebert/version'
|
2
|
+
|
1
3
|
module Quebert
|
2
4
|
autoload :Serializer, 'quebert/serializer'
|
3
5
|
autoload :Configuration, 'quebert/configuration'
|
@@ -8,6 +10,7 @@ module Quebert
|
|
8
10
|
autoload :Worker, 'quebert/worker'
|
9
11
|
autoload :CommandLineRunner, 'quebert/command_line_runner'
|
10
12
|
autoload :AsyncSender, 'quebert/async_sender'
|
13
|
+
autoload :Logging, 'quebert/logging'
|
11
14
|
|
12
15
|
class << self
|
13
16
|
def configuration
|
data/quebert.gemspec
CHANGED
@@ -1,111 +1,28 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "quebert/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |s|
|
7
|
-
s.name
|
8
|
-
s.version
|
9
|
-
|
10
|
-
s.
|
11
|
-
s.
|
12
|
-
s.
|
13
|
-
s.default_executable = %q{quebert}
|
6
|
+
s.name = "quebert"
|
7
|
+
s.version = Quebert::VERSION
|
8
|
+
s.authors = ["Brad Gessler", "Steel Fu", "Jeff Vyduna"]
|
9
|
+
s.email = ["brad@bradgessler.com"]
|
10
|
+
s.homepage = "http://github.com/polleverywhere/quebert"
|
11
|
+
s.summary = %q{A worker queue framework built around beanstalkd}
|
14
12
|
s.description = %q{A worker queue framework built around beanstalkd}
|
15
|
-
s.email = %q{brad@bradgessler.com}
|
16
|
-
s.executables = ["quebert"]
|
17
|
-
s.extra_rdoc_files = [
|
18
|
-
"LICENSE",
|
19
|
-
"README.rdoc"
|
20
|
-
]
|
21
|
-
s.files = [
|
22
|
-
".document",
|
23
|
-
"Gemfile",
|
24
|
-
"LICENSE",
|
25
|
-
"README.rdoc",
|
26
|
-
"Rakefile",
|
27
|
-
"VERSION",
|
28
|
-
"bin/quebert",
|
29
|
-
"lib/quebert.rb",
|
30
|
-
"lib/quebert/async_sender.rb",
|
31
|
-
"lib/quebert/async_sender/active_record.rb",
|
32
|
-
"lib/quebert/async_sender/class.rb",
|
33
|
-
"lib/quebert/async_sender/instance.rb",
|
34
|
-
"lib/quebert/async_sender/object.rb",
|
35
|
-
"lib/quebert/backend.rb",
|
36
|
-
"lib/quebert/backend/beanstalk.rb",
|
37
|
-
"lib/quebert/backend/in_process.rb",
|
38
|
-
"lib/quebert/backend/sync.rb",
|
39
|
-
"lib/quebert/command_line_runner.rb",
|
40
|
-
"lib/quebert/configuration.rb",
|
41
|
-
"lib/quebert/controller.rb",
|
42
|
-
"lib/quebert/controller/base.rb",
|
43
|
-
"lib/quebert/controller/beanstalk.rb",
|
44
|
-
"lib/quebert/job.rb",
|
45
|
-
"lib/quebert/serializer.rb",
|
46
|
-
"lib/quebert/support.rb",
|
47
|
-
"lib/quebert/support/pid_file.rb",
|
48
|
-
"lib/quebert/support/registry.rb",
|
49
|
-
"lib/quebert/worker.rb",
|
50
|
-
"quebert.gemspec",
|
51
|
-
"spec/async_sender_spec.rb",
|
52
|
-
"spec/backend_spec.rb",
|
53
|
-
"spec/command_line_runner_spec.rb",
|
54
|
-
"spec/configuration_spec.rb",
|
55
|
-
"spec/consumer_spec.rb",
|
56
|
-
"spec/job_spec.rb",
|
57
|
-
"spec/quebert_spec.rb",
|
58
|
-
"spec/serializer_spec.rb",
|
59
|
-
"spec/spec.opts",
|
60
|
-
"spec/spec_helper.rb",
|
61
|
-
"spec/support/active_record.rb",
|
62
|
-
"spec/support/jobs.rb",
|
63
|
-
"spec/support_spec.rb",
|
64
|
-
"spec/worker_spec.rb"
|
65
|
-
]
|
66
|
-
s.homepage = %q{http://github.com/bradgessler/quebert}
|
67
|
-
s.require_paths = ["lib"]
|
68
|
-
s.rubygems_version = %q{1.3.7}
|
69
|
-
s.summary = %q{A worker queue framework built around beanstalkd}
|
70
|
-
s.test_files = [
|
71
|
-
"spec/async_sender_spec.rb",
|
72
|
-
"spec/backend_spec.rb",
|
73
|
-
"spec/command_line_runner_spec.rb",
|
74
|
-
"spec/configuration_spec.rb",
|
75
|
-
"spec/consumer_spec.rb",
|
76
|
-
"spec/job_spec.rb",
|
77
|
-
"spec/quebert_spec.rb",
|
78
|
-
"spec/serializer_spec.rb",
|
79
|
-
"spec/spec_helper.rb",
|
80
|
-
"spec/support/active_record.rb",
|
81
|
-
"spec/support/jobs.rb",
|
82
|
-
"spec/support_spec.rb",
|
83
|
-
"spec/worker_spec.rb"
|
84
|
-
]
|
85
13
|
|
86
|
-
|
87
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
88
|
-
s.specification_version = 3
|
14
|
+
s.rubyforge_project = "quebert"
|
89
15
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
s.add_runtime_dependency(%q<json>, [">= 0"])
|
95
|
-
s.add_runtime_dependency(%q<beanstalk-client>, [">= 0"])
|
96
|
-
else
|
97
|
-
s.add_dependency(%q<json>, [">= 0"])
|
98
|
-
s.add_dependency(%q<beanstalk-client>, [">= 0"])
|
99
|
-
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
100
|
-
s.add_dependency(%q<json>, [">= 0"])
|
101
|
-
s.add_dependency(%q<beanstalk-client>, [">= 0"])
|
102
|
-
end
|
103
|
-
else
|
104
|
-
s.add_dependency(%q<json>, [">= 0"])
|
105
|
-
s.add_dependency(%q<beanstalk-client>, [">= 0"])
|
106
|
-
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
107
|
-
s.add_dependency(%q<json>, [">= 0"])
|
108
|
-
s.add_dependency(%q<beanstalk-client>, [">= 0"])
|
109
|
-
end
|
110
|
-
end
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
111
20
|
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
# s.add_development_dependency "rspec"
|
23
|
+
s.add_runtime_dependency "json"
|
24
|
+
s.add_runtime_dependency "beanstalk-client"
|
25
|
+
s.add_runtime_dependency "system_timer"
|
26
|
+
|
27
|
+
s.add_development_dependency 'rspec', '1.3.0'
|
28
|
+
end
|
data/spec/consumer_spec.rb
CHANGED
@@ -71,4 +71,29 @@ describe Controller::Beanstalk do
|
|
71
71
|
@q.peek_buried.should_not be_nil
|
72
72
|
end
|
73
73
|
end
|
74
|
+
|
75
|
+
it "should retry a job with a delay and then bury" do
|
76
|
+
@q.put TimeoutJob.new
|
77
|
+
@q.peek_ready.should_not be_nil
|
78
|
+
job = @q.reserve
|
79
|
+
job.beanstalk_job.stats["releases"].should eql(0)
|
80
|
+
job.beanstalk_job.stats["delay"].should eql(0)
|
81
|
+
lambda{job.perform}.should raise_exception(Quebert::Job::Timeout)
|
82
|
+
|
83
|
+
@q.peek_ready.should be_nil
|
84
|
+
beanstalk_job = @q.peek_delayed
|
85
|
+
beanstalk_job.should_not be_nil
|
86
|
+
beanstalk_job.stats["releases"].should eql(1)
|
87
|
+
beanstalk_job.stats["delay"].should eql(Quebert::Controller::Beanstalk::TIMEOUT_RETRY_GROWTH_RATE**beanstalk_job.stats["releases"])
|
88
|
+
|
89
|
+
sleep(3)
|
90
|
+
|
91
|
+
# lets set the max retry delay so it should bury instead of delay
|
92
|
+
Quebert::Controller::Beanstalk::MAX_TIMEOUT_RETRY_DELAY = 1
|
93
|
+
lambda{@q.reserve.perform}.should raise_exception(Quebert::Job::Timeout)
|
94
|
+
|
95
|
+
@q.peek_ready.should be_nil
|
96
|
+
@q.peek_delayed.should be_nil
|
97
|
+
@q.peek_buried.should_not be_nil
|
98
|
+
end
|
74
99
|
end
|
data/spec/job_spec.rb
CHANGED
@@ -48,7 +48,6 @@ describe Quebert::Job do
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
|
52
51
|
context "job queue" do
|
53
52
|
it "should enqueue" do
|
54
53
|
lambda{
|
@@ -85,5 +84,13 @@ describe Quebert::Job do
|
|
85
84
|
job.beanstalk_job.ttr.should eql(300)
|
86
85
|
end
|
87
86
|
end
|
88
|
-
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "Timeout" do
|
90
|
+
it "should respect TTR option" do
|
91
|
+
lambda {
|
92
|
+
TimeoutJob.new.perform!
|
93
|
+
}.should raise_exception(Quebert::Job::Timeout)
|
94
|
+
end
|
95
|
+
end
|
89
96
|
end
|
data/spec/support/jobs.rb
CHANGED
@@ -16,6 +16,19 @@ class BuryJob < Quebert::Job
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
class TimeoutJob < Quebert::Job
|
20
|
+
def perform!
|
21
|
+
# 1 second TTR
|
22
|
+
@ttr = 1
|
23
|
+
super
|
24
|
+
end
|
25
|
+
|
26
|
+
def perform
|
27
|
+
# 10 second task should definitely raise a Job::Timeout exception
|
28
|
+
sleep(10)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
19
32
|
class Adder < Quebert::Job
|
20
33
|
def perform(*args)
|
21
34
|
args.inject(0){|sum, n| sum = sum + n}
|
metadata
CHANGED
@@ -1,24 +1,28 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quebert
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 13
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 9
|
10
|
+
version: 0.0.9
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Brad Gessler
|
14
|
+
- Steel Fu
|
15
|
+
- Jeff Vyduna
|
14
16
|
autorequire:
|
15
17
|
bindir: bin
|
16
18
|
cert_chain: []
|
17
19
|
|
18
|
-
date: 2011-
|
19
|
-
default_executable:
|
20
|
+
date: 2011-11-14 00:00:00 -08:00
|
21
|
+
default_executable:
|
20
22
|
dependencies:
|
21
23
|
- !ruby/object:Gem::Dependency
|
24
|
+
name: json
|
25
|
+
prerelease: false
|
22
26
|
requirement: &id001 !ruby/object:Gem::Requirement
|
23
27
|
none: false
|
24
28
|
requirements:
|
@@ -29,10 +33,10 @@ dependencies:
|
|
29
33
|
- 0
|
30
34
|
version: "0"
|
31
35
|
type: :runtime
|
32
|
-
name: json
|
33
|
-
prerelease: false
|
34
36
|
version_requirements: *id001
|
35
37
|
- !ruby/object:Gem::Dependency
|
38
|
+
name: beanstalk-client
|
39
|
+
prerelease: false
|
36
40
|
requirement: &id002 !ruby/object:Gem::Requirement
|
37
41
|
none: false
|
38
42
|
requirements:
|
@@ -43,27 +47,11 @@ dependencies:
|
|
43
47
|
- 0
|
44
48
|
version: "0"
|
45
49
|
type: :runtime
|
46
|
-
name: beanstalk-client
|
47
|
-
prerelease: false
|
48
50
|
version_requirements: *id002
|
49
51
|
- !ruby/object:Gem::Dependency
|
50
|
-
|
51
|
-
none: false
|
52
|
-
requirements:
|
53
|
-
- - ">="
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
hash: 13
|
56
|
-
segments:
|
57
|
-
- 1
|
58
|
-
- 2
|
59
|
-
- 9
|
60
|
-
version: 1.2.9
|
61
|
-
type: :development
|
62
|
-
name: rspec
|
52
|
+
name: system_timer
|
63
53
|
prerelease: false
|
64
|
-
|
65
|
-
- !ruby/object:Gem::Dependency
|
66
|
-
requirement: &id004 !ruby/object:Gem::Requirement
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
67
55
|
none: false
|
68
56
|
requirements:
|
69
57
|
- - ">="
|
@@ -73,39 +61,40 @@ dependencies:
|
|
73
61
|
- 0
|
74
62
|
version: "0"
|
75
63
|
type: :runtime
|
76
|
-
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: *id004
|
64
|
+
version_requirements: *id003
|
79
65
|
- !ruby/object:Gem::Dependency
|
80
|
-
|
66
|
+
name: rspec
|
67
|
+
prerelease: false
|
68
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
81
69
|
none: false
|
82
70
|
requirements:
|
83
|
-
- - "
|
71
|
+
- - "="
|
84
72
|
- !ruby/object:Gem::Version
|
85
|
-
hash:
|
73
|
+
hash: 27
|
86
74
|
segments:
|
75
|
+
- 1
|
76
|
+
- 3
|
87
77
|
- 0
|
88
|
-
version:
|
89
|
-
type: :
|
90
|
-
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: *id005
|
78
|
+
version: 1.3.0
|
79
|
+
type: :development
|
80
|
+
version_requirements: *id004
|
93
81
|
description: A worker queue framework built around beanstalkd
|
94
|
-
email:
|
82
|
+
email:
|
83
|
+
- brad@bradgessler.com
|
95
84
|
executables:
|
96
85
|
- quebert
|
97
86
|
extensions: []
|
98
87
|
|
99
|
-
extra_rdoc_files:
|
100
|
-
|
101
|
-
- README.rdoc
|
88
|
+
extra_rdoc_files: []
|
89
|
+
|
102
90
|
files:
|
103
91
|
- .document
|
92
|
+
- .gitignore
|
104
93
|
- Gemfile
|
94
|
+
- Guardfile
|
105
95
|
- LICENSE
|
106
96
|
- README.rdoc
|
107
97
|
- Rakefile
|
108
|
-
- VERSION
|
109
98
|
- bin/quebert
|
110
99
|
- lib/quebert.rb
|
111
100
|
- lib/quebert/async_sender.rb
|
@@ -123,10 +112,12 @@ files:
|
|
123
112
|
- lib/quebert/controller/base.rb
|
124
113
|
- lib/quebert/controller/beanstalk.rb
|
125
114
|
- lib/quebert/job.rb
|
115
|
+
- lib/quebert/logging.rb
|
126
116
|
- lib/quebert/serializer.rb
|
127
117
|
- lib/quebert/support.rb
|
128
118
|
- lib/quebert/support/pid_file.rb
|
129
119
|
- lib/quebert/support/registry.rb
|
120
|
+
- lib/quebert/version.rb
|
130
121
|
- lib/quebert/worker.rb
|
131
122
|
- quebert.gemspec
|
132
123
|
- spec/async_sender_spec.rb
|
@@ -144,7 +135,7 @@ files:
|
|
144
135
|
- spec/support_spec.rb
|
145
136
|
- spec/worker_spec.rb
|
146
137
|
has_rdoc: true
|
147
|
-
homepage: http://github.com/
|
138
|
+
homepage: http://github.com/polleverywhere/quebert
|
148
139
|
licenses: []
|
149
140
|
|
150
141
|
post_install_message:
|
@@ -172,8 +163,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
172
163
|
version: "0"
|
173
164
|
requirements: []
|
174
165
|
|
175
|
-
rubyforge_project:
|
176
|
-
rubygems_version: 1.
|
166
|
+
rubyforge_project: quebert
|
167
|
+
rubygems_version: 1.6.2
|
177
168
|
signing_key:
|
178
169
|
specification_version: 3
|
179
170
|
summary: A worker queue framework built around beanstalkd
|
@@ -186,6 +177,7 @@ test_files:
|
|
186
177
|
- spec/job_spec.rb
|
187
178
|
- spec/quebert_spec.rb
|
188
179
|
- spec/serializer_spec.rb
|
180
|
+
- spec/spec.opts
|
189
181
|
- spec/spec_helper.rb
|
190
182
|
- spec/support/active_record.rb
|
191
183
|
- spec/support/jobs.rb
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.0.8
|