quebert 0.0.0 → 0.0.1
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/Gemfile +0 -1
- data/README.rdoc +2 -2
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/bin/quebert +13 -0
- data/lib/quebert.rb +17 -14
- data/lib/quebert/backend.rb +0 -4
- data/lib/quebert/command_line_runner.rb +40 -0
- data/lib/quebert/configuration.rb +19 -6
- data/lib/quebert/support.rb +4 -0
- data/lib/quebert/support/pid_file.rb +72 -0
- data/lib/quebert/support/registry.rb +13 -0
- data/lib/quebert/worker.rb +17 -7
- data/quebert.gemspec +13 -6
- data/spec/backend_spec.rb +6 -1
- data/spec/command_line_runner_spec.rb +77 -0
- data/spec/configuration_spec.rb +1 -1
- data/spec/spec_helper.rb +14 -1
- metadata +14 -9
- data/lib/quebert/daemonizing.rb +0 -144
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
@@ -7,11 +7,11 @@ A worker queue framework designed around Beanstalk. Features include:
|
|
7
7
|
= Features
|
8
8
|
|
9
9
|
* [x] Multiple back-ends (InProcess, Sync, and Beanstalk)
|
10
|
-
* [
|
10
|
+
* [ ] Rails/ActiveRecord integration similar to async_observer
|
11
11
|
* [ ] Pluggable exception handling (for Hoptoad integration)
|
12
12
|
* [ ] Reliable daemonization with pidfile support
|
13
13
|
|
14
|
-
[x] = Completed, [ ] = Not Started
|
14
|
+
[x] = Completed, [ ] = Not Started
|
15
15
|
|
16
16
|
= How to use
|
17
17
|
|
data/Rakefile
CHANGED
@@ -11,7 +11,7 @@ begin
|
|
11
11
|
gem.authors = ["Brad Gessler"]
|
12
12
|
gem.add_development_dependency "rspec", ">= 1.2.9"
|
13
13
|
gem.add_dependency "json"
|
14
|
-
gem.add_dependency "
|
14
|
+
gem.add_dependency "optitron"
|
15
15
|
gem.add_dependency "beanstalk-client"
|
16
16
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
17
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.1
|
data/bin/quebert
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
begin
|
4
|
+
require "quebert"
|
5
|
+
rescue LoadError
|
6
|
+
quebert_path = File.expand_path('../../lib/', __FILE__)
|
7
|
+
$:.unshift(quebert_path)
|
8
|
+
require 'rubygems'
|
9
|
+
require 'bundler/setup'
|
10
|
+
require 'quebert'
|
11
|
+
end
|
12
|
+
|
13
|
+
Quebert::CommandLineRunner.dispatch
|
data/lib/quebert.rb
CHANGED
@@ -1,14 +1,12 @@
|
|
1
|
-
$:.unshift File.join(File.dirname(__FILE__), 'quebert')
|
2
|
-
|
3
1
|
module Quebert
|
4
|
-
autoload :Configuration,
|
5
|
-
autoload :Job,
|
6
|
-
autoload :Consumer,
|
7
|
-
autoload :Backend,
|
8
|
-
autoload :Support,
|
9
|
-
autoload :Worker,
|
10
|
-
autoload :
|
11
|
-
autoload :AsyncSender,
|
2
|
+
autoload :Configuration, 'quebert/configuration'
|
3
|
+
autoload :Job, 'quebert/job'
|
4
|
+
autoload :Consumer, 'quebert/consumer'
|
5
|
+
autoload :Backend, 'quebert/backend'
|
6
|
+
autoload :Support, 'quebert/support'
|
7
|
+
autoload :Worker, 'quebert/worker'
|
8
|
+
autoload :CommandLineRunner, 'quebert/command_line_runner'
|
9
|
+
autoload :AsyncSender, 'quebert/async_sender'
|
12
10
|
|
13
11
|
class << self
|
14
12
|
def configuration
|
@@ -18,12 +16,17 @@ module Quebert
|
|
18
16
|
|
19
17
|
# Registry for quebert backends
|
20
18
|
def backends
|
21
|
-
@backends ||=
|
19
|
+
@backends ||= Support::Registry.new
|
20
|
+
end
|
21
|
+
|
22
|
+
# Make this easier for elsewhere in the app
|
23
|
+
def logger
|
24
|
+
config.logger
|
22
25
|
end
|
23
26
|
end
|
24
27
|
|
25
28
|
# Register built-in Quebert backends
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
Quebert.backends.register :beanstalk, Backend::Beanstalk
|
30
|
+
Quebert.backends.register :in_process, Backend::InProcess
|
31
|
+
Quebert.backends.register :sync, Backend::Sync
|
29
32
|
end
|
data/lib/quebert/backend.rb
CHANGED
@@ -3,9 +3,5 @@ module Quebert
|
|
3
3
|
autoload :InProcess, 'quebert/backend/in_process.rb'
|
4
4
|
autoload :Beanstalk, 'quebert/backend/beanstalk.rb'
|
5
5
|
autoload :Sync, 'quebert/backend/sync.rb'
|
6
|
-
|
7
|
-
def self.register(name, backend)
|
8
|
-
Quebert.backends[name.to_sym] = backend
|
9
|
-
end
|
10
6
|
end
|
11
7
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'optitron'
|
2
|
+
|
3
|
+
module Quebert
|
4
|
+
class CommandLineRunner < Optitron::CLI
|
5
|
+
|
6
|
+
desc "Starts a quebert worker"
|
7
|
+
opt "pid-file", :type => :string
|
8
|
+
opt "log-file", :type => :string
|
9
|
+
opt "config-file", :type => :string
|
10
|
+
opt "chdir", :type => :string
|
11
|
+
def worker
|
12
|
+
if dir = params['chdir']
|
13
|
+
Dir.chdir dir
|
14
|
+
end
|
15
|
+
|
16
|
+
if pid_file = params['pid-file']
|
17
|
+
Support::PidFile.new(pid_file).write!
|
18
|
+
end
|
19
|
+
|
20
|
+
if log_path = params['log-file']
|
21
|
+
Quebert.config.log_file_path = log_path
|
22
|
+
end
|
23
|
+
|
24
|
+
if config = params['config-file'] || auto_config
|
25
|
+
require config
|
26
|
+
end
|
27
|
+
|
28
|
+
Worker.new.start
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def auto_config
|
33
|
+
rails_env_path = './config/environment.rb'
|
34
|
+
if File.exists?(rails_env_path)
|
35
|
+
Quebert.logger.info "Detected Rails! Setting config-file=#{File.expand_path(rails_env_path)}"
|
36
|
+
rails_env_path
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,16 +1,29 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
1
3
|
module Quebert
|
2
4
|
class Configuration
|
3
|
-
attr_accessor :backend
|
5
|
+
attr_accessor :backend, :logger
|
4
6
|
|
5
|
-
def
|
6
|
-
|
7
|
+
def logger
|
8
|
+
@logger ||= Logger.new($stdout)
|
9
|
+
end
|
10
|
+
|
11
|
+
def log_file_path=(path)
|
12
|
+
self.logger = Logger.new(path)
|
13
|
+
end
|
14
|
+
|
15
|
+
def from_hash(hash)
|
16
|
+
hash = Support.symbolize_keys(hash)
|
7
17
|
# Find out backend from the registry and configure
|
8
18
|
if backend = Quebert.backends[hash.delete(:backend).to_sym]
|
9
19
|
# If the backend supports configuration, do it!
|
10
|
-
|
11
|
-
config.backend = backend.respond_to?(:configure) ? backend.configure(Support.symbolize_keys(hash)) : backend.new
|
20
|
+
self.backend = backend.respond_to?(:configure) ? backend.configure(Support.symbolize_keys(hash)) : backend.new
|
12
21
|
end
|
13
|
-
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.from_hash(hash)
|
26
|
+
new.from_hash(hash) # Config this puppy up from a config hash
|
14
27
|
end
|
15
28
|
end
|
16
29
|
end
|
data/lib/quebert/support.rb
CHANGED
@@ -0,0 +1,72 @@
|
|
1
|
+
module Quebert
|
2
|
+
module Support
|
3
|
+
|
4
|
+
# Deal with all of our pid file stuff
|
5
|
+
class PidFile
|
6
|
+
|
7
|
+
attr_reader :path
|
8
|
+
|
9
|
+
ProcessRunning = Class.new(RuntimeError)
|
10
|
+
|
11
|
+
def initialize(path)
|
12
|
+
@path = path
|
13
|
+
end
|
14
|
+
|
15
|
+
def write!
|
16
|
+
remove_stale and write
|
17
|
+
end
|
18
|
+
|
19
|
+
# Read pids and turn them into ints
|
20
|
+
def self.read(file)
|
21
|
+
if File.file?(file) && pid = File.read(file)
|
22
|
+
pid.to_i
|
23
|
+
else
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Tells us if a current process is running
|
29
|
+
def self.running?(pid)
|
30
|
+
Process.getpgid(pid) != -1
|
31
|
+
rescue Errno::EPERM
|
32
|
+
true
|
33
|
+
rescue Errno::ESRCH
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
# If PID file is stale, remove it.
|
39
|
+
def remove_stale
|
40
|
+
if exists? && running?
|
41
|
+
raise ProcessRunning, "#{path} already exists, seems like it's already running (process ID: #{pid}). " +
|
42
|
+
"Stop the process or delete #{path}."
|
43
|
+
else
|
44
|
+
remove
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def remove
|
49
|
+
File.delete(path) if exists?
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
def write
|
54
|
+
File.open(path,"w") { |f| f.write(Process.pid) }
|
55
|
+
File.chmod(0644, path)
|
56
|
+
end
|
57
|
+
|
58
|
+
def pid
|
59
|
+
self.class.read(path)
|
60
|
+
end
|
61
|
+
|
62
|
+
def running?
|
63
|
+
self.class.running?(pid)
|
64
|
+
end
|
65
|
+
|
66
|
+
def exists?
|
67
|
+
File.exist?(path)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
data/lib/quebert/worker.rb
CHANGED
@@ -2,9 +2,7 @@ require 'logger'
|
|
2
2
|
|
3
3
|
module Quebert
|
4
4
|
class Worker
|
5
|
-
attr_accessor :exception_handler, :
|
6
|
-
|
7
|
-
include Quebert::Daemonizable
|
5
|
+
attr_accessor :exception_handler, :logger, :backend
|
8
6
|
|
9
7
|
def initialize
|
10
8
|
yield self if block_given?
|
@@ -12,18 +10,30 @@ module Quebert
|
|
12
10
|
|
13
11
|
# Start the worker backend and intercept exceptions if a handler is provided
|
14
12
|
def start
|
15
|
-
|
13
|
+
logger.info "Worker pid##{Process.pid} started with #{backend.class.name} backend"
|
14
|
+
while consumer = backend.reserve do
|
16
15
|
begin
|
17
|
-
job.
|
16
|
+
log consumer.job, "performing with args #{consumer.job.args.inspect}"
|
17
|
+
consumer.perform
|
18
|
+
log consumer.job, "complete"
|
18
19
|
rescue Exception => e
|
20
|
+
log consumer.job, "fault #{e}", :error
|
19
21
|
exception_handler ? exception_handler.call(e) : raise(e)
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
24
26
|
protected
|
25
|
-
def log(message)
|
26
|
-
|
27
|
+
def log(job, message, level=:info)
|
28
|
+
logger.send(level, "#{job.class.name}##{job.object_id}: #{message}")
|
29
|
+
end
|
30
|
+
|
31
|
+
def logger
|
32
|
+
@logger ||= Quebert.logger
|
33
|
+
end
|
34
|
+
|
35
|
+
def backend
|
36
|
+
@backend ||= Quebert.config.backend
|
27
37
|
end
|
28
38
|
end
|
29
39
|
end
|
data/quebert.gemspec
CHANGED
@@ -5,13 +5,15 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{quebert}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Brad Gessler"]
|
12
|
-
s.date = %q{2010-10-
|
12
|
+
s.date = %q{2010-10-04}
|
13
|
+
s.default_executable = %q{quebert}
|
13
14
|
s.description = %q{A worker queue framework built around beanstalkd}
|
14
15
|
s.email = %q{brad@bradgessler.com}
|
16
|
+
s.executables = ["quebert"]
|
15
17
|
s.extra_rdoc_files = [
|
16
18
|
"LICENSE",
|
17
19
|
"README.rdoc"
|
@@ -24,23 +26,27 @@ Gem::Specification.new do |s|
|
|
24
26
|
"README.rdoc",
|
25
27
|
"Rakefile",
|
26
28
|
"VERSION",
|
29
|
+
"bin/quebert",
|
27
30
|
"lib/quebert.rb",
|
28
31
|
"lib/quebert/async_sender.rb",
|
29
32
|
"lib/quebert/backend.rb",
|
30
33
|
"lib/quebert/backend/beanstalk.rb",
|
31
34
|
"lib/quebert/backend/in_process.rb",
|
32
35
|
"lib/quebert/backend/sync.rb",
|
36
|
+
"lib/quebert/command_line_runner.rb",
|
33
37
|
"lib/quebert/configuration.rb",
|
34
38
|
"lib/quebert/consumer.rb",
|
35
39
|
"lib/quebert/consumer/base.rb",
|
36
40
|
"lib/quebert/consumer/beanstalk.rb",
|
37
|
-
"lib/quebert/daemonizing.rb",
|
38
41
|
"lib/quebert/job.rb",
|
39
42
|
"lib/quebert/support.rb",
|
43
|
+
"lib/quebert/support/pid_file.rb",
|
44
|
+
"lib/quebert/support/registry.rb",
|
40
45
|
"lib/quebert/worker.rb",
|
41
46
|
"quebert.gemspec",
|
42
47
|
"spec/async_sender_spec.rb",
|
43
48
|
"spec/backend_spec.rb",
|
49
|
+
"spec/command_line_runner_spec.rb",
|
44
50
|
"spec/configuration_spec.rb",
|
45
51
|
"spec/consumer_spec.rb",
|
46
52
|
"spec/job_spec.rb",
|
@@ -58,6 +64,7 @@ Gem::Specification.new do |s|
|
|
58
64
|
s.test_files = [
|
59
65
|
"spec/async_sender_spec.rb",
|
60
66
|
"spec/backend_spec.rb",
|
67
|
+
"spec/command_line_runner_spec.rb",
|
61
68
|
"spec/configuration_spec.rb",
|
62
69
|
"spec/consumer_spec.rb",
|
63
70
|
"spec/job_spec.rb",
|
@@ -74,18 +81,18 @@ Gem::Specification.new do |s|
|
|
74
81
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
75
82
|
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
76
83
|
s.add_runtime_dependency(%q<json>, [">= 0"])
|
77
|
-
s.add_runtime_dependency(%q<
|
84
|
+
s.add_runtime_dependency(%q<optitron>, [">= 0"])
|
78
85
|
s.add_runtime_dependency(%q<beanstalk-client>, [">= 0"])
|
79
86
|
else
|
80
87
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
81
88
|
s.add_dependency(%q<json>, [">= 0"])
|
82
|
-
s.add_dependency(%q<
|
89
|
+
s.add_dependency(%q<optitron>, [">= 0"])
|
83
90
|
s.add_dependency(%q<beanstalk-client>, [">= 0"])
|
84
91
|
end
|
85
92
|
else
|
86
93
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
87
94
|
s.add_dependency(%q<json>, [">= 0"])
|
88
|
-
s.add_dependency(%q<
|
95
|
+
s.add_dependency(%q<optitron>, [">= 0"])
|
89
96
|
s.add_dependency(%q<beanstalk-client>, [">= 0"])
|
90
97
|
end
|
91
98
|
end
|
data/spec/backend_spec.rb
CHANGED
@@ -6,9 +6,14 @@ describe Backend do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
it "should register backends" do
|
9
|
-
Quebert
|
9
|
+
Quebert.backends.register :twenty, 20
|
10
10
|
Quebert.backends[:twenty].should eql(20)
|
11
11
|
end
|
12
|
+
|
13
|
+
it "should unregister backends" do
|
14
|
+
Quebert.backends.unregister :twenty
|
15
|
+
Quebert.backends[:twenty].should be_nil
|
16
|
+
end
|
12
17
|
end
|
13
18
|
|
14
19
|
describe Backend::InProcess do
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe CommandLineRunner do
|
4
|
+
before(:all) do
|
5
|
+
Quebert.config.backend = Backend::InProcess.new
|
6
|
+
end
|
7
|
+
|
8
|
+
context "log-file" do
|
9
|
+
it "should write log file" do
|
10
|
+
clean_file 'log.log' do
|
11
|
+
lambda{
|
12
|
+
CommandLineRunner.dispatch(%w(worker --log-file=log.log))
|
13
|
+
}.should change { File.read('log.log') if File.exists?('log.log') }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "pid-file" do
|
19
|
+
it "should write pid" do
|
20
|
+
clean_file 'pid.pid' do
|
21
|
+
File.exists?('pid').should be_false
|
22
|
+
CommandLineRunner.dispatch(%w(worker --pid-file=pid.pid))
|
23
|
+
Support::PidFile.read('pid.pid').should eql(Process.pid)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should remove stale" do
|
28
|
+
clean_file 'pid.pid', "-1" do
|
29
|
+
CommandLineRunner.dispatch(%w(worker --pid-file=pid.pid))
|
30
|
+
Support::PidFile.read('pid.pid').should eql(Process.pid)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should complain if the pid is already running" do
|
35
|
+
clean_file 'pid.pid', Process.pid do
|
36
|
+
lambda{
|
37
|
+
CommandLineRunner.dispatch(%w(worker --pid-file=pid.pid))
|
38
|
+
}.should raise_exception(Support::PidFile::ProcessRunning)
|
39
|
+
Support::PidFile.read('pid.pid').should eql(Process.pid)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "config-file" do
|
45
|
+
it "should auto-detect rails environment file" do
|
46
|
+
clean_file './config/environment.rb', "raise 'RailsConfig'" do
|
47
|
+
lambda{
|
48
|
+
CommandLineRunner.dispatch(%w(worker))
|
49
|
+
}.should raise_exception('RailsConfig')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should run config file" do
|
54
|
+
clean_file './super_awesome.rb', "raise 'SuperAwesome'" do
|
55
|
+
lambda{
|
56
|
+
CommandLineRunner.dispatch(%w(worker --config-file=super_awesome.rb))
|
57
|
+
}.should raise_exception('SuperAwesome')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
context "chdir" do
|
64
|
+
before(:each) do
|
65
|
+
@chdir = Dir.pwd
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should change chdir" do
|
69
|
+
CommandLineRunner.dispatch(%w(worker --chdir=/))
|
70
|
+
Dir.pwd.should eql('/')
|
71
|
+
end
|
72
|
+
|
73
|
+
after(:each) do
|
74
|
+
Dir.chdir(@chdir)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/spec/configuration_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
3
3
|
describe Configuration do
|
4
4
|
context "from hash" do
|
5
5
|
before(:all) do
|
6
|
-
@config = Configuration.from_hash('backend' => 'beanstalk', 'host' => 'localhost:11300', 'tube' => 'quebert-config-test')
|
6
|
+
@config = Configuration.new.from_hash('backend' => 'beanstalk', 'host' => 'localhost:11300', 'tube' => 'quebert-config-test')
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should configure backend" do
|
data/spec/spec_helper.rb
CHANGED
@@ -7,10 +7,23 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
7
7
|
require 'quebert'
|
8
8
|
require 'spec'
|
9
9
|
require 'spec/autorun'
|
10
|
+
require 'logger'
|
10
11
|
|
11
12
|
Spec::Runner.configure do |config|
|
12
13
|
end
|
13
14
|
|
14
15
|
include Quebert
|
16
|
+
Quebert.config.logger = Logger.new('/dev/null') # Shhh...
|
15
17
|
|
16
|
-
require 'jobs'
|
18
|
+
require 'jobs'
|
19
|
+
|
20
|
+
def clean_file(path, contents=nil, &block)
|
21
|
+
FileUtils.remove_entry(path) if File.exists?(path)
|
22
|
+
FileUtils.mkdir_p(File.dirname(path))
|
23
|
+
begin
|
24
|
+
File.open(path, 'w'){|f| f.write(contents == :empty ? nil : contents) } unless contents.nil?
|
25
|
+
block.call
|
26
|
+
ensure
|
27
|
+
FileUtils.remove_entry(path) if File.exists?(path) and path != './' # Yeah! This has happened before :(
|
28
|
+
end
|
29
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quebert
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 29
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Brad Gessler
|
@@ -15,8 +15,8 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-10-
|
19
|
-
default_executable:
|
18
|
+
date: 2010-10-04 00:00:00 -07:00
|
19
|
+
default_executable: quebert
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
name: rspec
|
@@ -49,7 +49,7 @@ dependencies:
|
|
49
49
|
type: :runtime
|
50
50
|
version_requirements: *id002
|
51
51
|
- !ruby/object:Gem::Dependency
|
52
|
-
name:
|
52
|
+
name: optitron
|
53
53
|
prerelease: false
|
54
54
|
requirement: &id003 !ruby/object:Gem::Requirement
|
55
55
|
none: false
|
@@ -78,8 +78,8 @@ dependencies:
|
|
78
78
|
version_requirements: *id004
|
79
79
|
description: A worker queue framework built around beanstalkd
|
80
80
|
email: brad@bradgessler.com
|
81
|
-
executables:
|
82
|
-
|
81
|
+
executables:
|
82
|
+
- quebert
|
83
83
|
extensions: []
|
84
84
|
|
85
85
|
extra_rdoc_files:
|
@@ -93,23 +93,27 @@ files:
|
|
93
93
|
- README.rdoc
|
94
94
|
- Rakefile
|
95
95
|
- VERSION
|
96
|
+
- bin/quebert
|
96
97
|
- lib/quebert.rb
|
97
98
|
- lib/quebert/async_sender.rb
|
98
99
|
- lib/quebert/backend.rb
|
99
100
|
- lib/quebert/backend/beanstalk.rb
|
100
101
|
- lib/quebert/backend/in_process.rb
|
101
102
|
- lib/quebert/backend/sync.rb
|
103
|
+
- lib/quebert/command_line_runner.rb
|
102
104
|
- lib/quebert/configuration.rb
|
103
105
|
- lib/quebert/consumer.rb
|
104
106
|
- lib/quebert/consumer/base.rb
|
105
107
|
- lib/quebert/consumer/beanstalk.rb
|
106
|
-
- lib/quebert/daemonizing.rb
|
107
108
|
- lib/quebert/job.rb
|
108
109
|
- lib/quebert/support.rb
|
110
|
+
- lib/quebert/support/pid_file.rb
|
111
|
+
- lib/quebert/support/registry.rb
|
109
112
|
- lib/quebert/worker.rb
|
110
113
|
- quebert.gemspec
|
111
114
|
- spec/async_sender_spec.rb
|
112
115
|
- spec/backend_spec.rb
|
116
|
+
- spec/command_line_runner_spec.rb
|
113
117
|
- spec/configuration_spec.rb
|
114
118
|
- spec/consumer_spec.rb
|
115
119
|
- spec/job_spec.rb
|
@@ -155,6 +159,7 @@ summary: A worker queue framework built around beanstalkd
|
|
155
159
|
test_files:
|
156
160
|
- spec/async_sender_spec.rb
|
157
161
|
- spec/backend_spec.rb
|
162
|
+
- spec/command_line_runner_spec.rb
|
158
163
|
- spec/configuration_spec.rb
|
159
164
|
- spec/consumer_spec.rb
|
160
165
|
- spec/job_spec.rb
|
data/lib/quebert/daemonizing.rb
DELETED
@@ -1,144 +0,0 @@
|
|
1
|
-
require 'etc'
|
2
|
-
require 'daemons'
|
3
|
-
require 'fileutils'
|
4
|
-
|
5
|
-
module Process
|
6
|
-
# Returns +true+ the process identied by +pid+ is running.
|
7
|
-
def running?(pid)
|
8
|
-
Process.getpgid(pid) != -1
|
9
|
-
rescue Errno::EPERM
|
10
|
-
true
|
11
|
-
rescue Errno::ESRCH
|
12
|
-
false
|
13
|
-
end
|
14
|
-
module_function :running?
|
15
|
-
end
|
16
|
-
|
17
|
-
module Quebert
|
18
|
-
module Daemonizable
|
19
|
-
attr_accessor :pid_file, :log_file
|
20
|
-
|
21
|
-
PidFileExist = Class.new(RuntimeError)
|
22
|
-
|
23
|
-
def self.included(base)
|
24
|
-
base.extend ClassMethods
|
25
|
-
end
|
26
|
-
|
27
|
-
def daemonize
|
28
|
-
raise ArgumentError, 'You must specify a pid_file to daemonize' unless pid_file
|
29
|
-
|
30
|
-
remove_stale_pid_file
|
31
|
-
|
32
|
-
pwd = Dir.pwd # Current directory is changed during daemonization, so store it
|
33
|
-
# HACK we need to create the directory before daemonization to prevent a bug under 1.9
|
34
|
-
# ignoring all signals when the directory is created after daemonization.
|
35
|
-
FileUtils.mkdir_p File.dirname(pid_file)
|
36
|
-
# Daemonize.daemonize(File.expand_path(@log_file), "quebert worker")
|
37
|
-
Daemonize.daemonize(File.expand_path(@log_file), "quebert")
|
38
|
-
Dir.chdir(pwd)
|
39
|
-
write_pid_file
|
40
|
-
end
|
41
|
-
|
42
|
-
def pid
|
43
|
-
File.exist?(pid_file) ? open(pid_file).read.to_i : nil
|
44
|
-
end
|
45
|
-
|
46
|
-
# Register a proc to be called to restart the server.
|
47
|
-
def on_restart(&block)
|
48
|
-
@on_restart = block
|
49
|
-
end
|
50
|
-
|
51
|
-
# Restart the server.
|
52
|
-
def restart
|
53
|
-
if @on_restart
|
54
|
-
log '>> Restarting ...'
|
55
|
-
stop
|
56
|
-
remove_pid_file
|
57
|
-
@on_restart.call
|
58
|
-
exit!
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
module ClassMethods
|
63
|
-
# Send a QUIT or INT (if timeout is +0+) signal the process which
|
64
|
-
# PID is stored in +pid_file+.
|
65
|
-
# If the process is still running after +timeout+, KILL signal is
|
66
|
-
# sent.
|
67
|
-
def kill(pid_file, timeout=60)
|
68
|
-
if timeout == 0
|
69
|
-
send_signal('INT', pid_file, timeout)
|
70
|
-
else
|
71
|
-
send_signal('QUIT', pid_file, timeout)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
# Restart the server by sending HUP signal.
|
76
|
-
def restart(pid_file)
|
77
|
-
send_signal('HUP', pid_file)
|
78
|
-
end
|
79
|
-
|
80
|
-
# Send a +signal+ to the process which PID is stored in +pid_file+.
|
81
|
-
def send_signal(signal, pid_file, timeout=60)
|
82
|
-
if pid = read_pid_file(pid_file)
|
83
|
-
Logging.log "Sending #{signal} signal to process #{pid} ... "
|
84
|
-
Process.kill(signal, pid)
|
85
|
-
Timeout.timeout(timeout) do
|
86
|
-
sleep 0.1 while Process.running?(pid)
|
87
|
-
end
|
88
|
-
else
|
89
|
-
Logging.log "Can't stop process, no PID found in #{pid_file}"
|
90
|
-
end
|
91
|
-
rescue Timeout::Error
|
92
|
-
Logging.log "Timeout!"
|
93
|
-
force_kill pid_file
|
94
|
-
rescue Interrupt
|
95
|
-
force_kill pid_file
|
96
|
-
rescue Errno::ESRCH # No such process
|
97
|
-
Logging.log "process not found!"
|
98
|
-
force_kill pid_file
|
99
|
-
end
|
100
|
-
|
101
|
-
def force_kill(pid_file)
|
102
|
-
if pid = read_pid_file(pid_file)
|
103
|
-
Logging.log "Sending KILL signal to process #{pid} ... "
|
104
|
-
Process.kill("KILL", pid)
|
105
|
-
File.delete(pid_file) if File.exist?(pid_file)
|
106
|
-
else
|
107
|
-
Logging.log "Can't stop process, no PID found in #{pid_file}"
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
def read_pid_file(file)
|
112
|
-
if File.file?(file) && pid = File.read(file)
|
113
|
-
pid.to_i
|
114
|
-
else
|
115
|
-
nil
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
protected
|
121
|
-
def remove_pid_file
|
122
|
-
File.delete(pid_file) if pid_file && File.exists?(pid_file)
|
123
|
-
end
|
124
|
-
|
125
|
-
def write_pid_file
|
126
|
-
log ">> Writing PID to #{pid_file}"
|
127
|
-
open(pid_file,"w") { |f| f.write(Process.pid) }
|
128
|
-
File.chmod(0644, pid_file)
|
129
|
-
end
|
130
|
-
|
131
|
-
# If PID file is stale, remove it.
|
132
|
-
def remove_stale_pid_file
|
133
|
-
if File.exist?(pid_file)
|
134
|
-
if pid && Process.running?(pid)
|
135
|
-
raise PidFileExist, "#{pid_file} already exists, seems like it's already running (process ID: #{pid}). " +
|
136
|
-
"Stop the process or delete #{pid_file}."
|
137
|
-
else
|
138
|
-
log ">> Deleting stale PID file #{pid_file}"
|
139
|
-
remove_pid_file
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|