rabbit-wq 1.9.0 → 2.0.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2567a7603af0d8e5b325f79a954b886d23f8a57a
4
- data.tar.gz: a2a959493098b42965c5c60bcd3c710cfdc9452f
3
+ metadata.gz: e8146dc0247a3db1e510b8c6205e8ede3892667a
4
+ data.tar.gz: f141d450c09d9b0a925ce0f398f45aadfd1430f5
5
5
  SHA512:
6
- metadata.gz: 7269f386abf1bb948ae772927ae2bd1965c258f86d8788395988122a5989f47740bfc4521aeae9d0f983a35599b8dae5b889eaf3f199e3d24e6f3e44dbfca64b
7
- data.tar.gz: 7028c4112949da07e0971a7e69e776080b69d5a082cd2bbfeb839f82f683bbf235269c8ee1906ccb3f18a467373676c407221dd90295352aa8385259acbfca22
6
+ metadata.gz: 7f62f6087f74838fb3b4b3f02a63c1e36663a714f192731203dafabc6f86c506d488fd43f14c270f1893094da87462aed35202592c07ca63d46708d3b80fde6d
7
+ data.tar.gz: 76bdc1c54aba7299d5b7ba993b5fe5782bd508e8e7450a915f226c3c91938a20974596b55ec5d3a0ce4390426b89161985c7318644964e1b1f0c7056b0efbad6
data/bin/rabbit-wq CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env ruby
2
- require 'rabbit_wq/cli'
3
- RabbitWQ::Cli.new( ARGV ).run
2
+ require 'rabbit_wq'
3
+ RabbitWQ::Cli.start
data/lib/rabbit_wq/cli.rb CHANGED
@@ -1,129 +1,14 @@
1
- require 'rubygems'
2
- require 'rabbit_wq'
3
- require 'trollop'
4
- require 'yell'
1
+ require 'servitude'
5
2
 
6
3
  module RabbitWQ
7
- class Cli
4
+ class Cli < ::Servitude::Cli::Service
8
5
 
9
- attr_reader :cmd,
10
- :options
6
+ no_commands do
11
7
 
12
- SUB_COMMANDS = %w(
13
- restart
14
- start
15
- status
16
- stop
17
- )
18
-
19
- DEFAULT_CONFIG_PATH = "/etc/#{APP_ID}/#{APP_ID}.conf"
20
- DEFAULT_LOG_PATH = "/var/log/#{APP_ID}/#{APP_ID}.log"
21
- DEFAULT_PID_PATH = "/var/run/#{APP_ID}/#{APP_ID}.pid"
22
-
23
- def initialize( args )
24
- Trollop::options do
25
- version VERSION_COPYRIGHT
26
- banner <<-EOS
27
- #{APP_NAME} #{VERSION_COPYRIGHT}
28
-
29
- Usage:
30
- #{APP_ID} [command] [options]
31
-
32
- commands:
33
- #{SUB_COMMANDS.map { |sub_cmd| " #{sub_cmd}" }.join( "\n" )}
34
-
35
- (For help with a command: #{APP_ID} [command] -h)
36
-
37
- options:
38
- EOS
39
- stop_on SUB_COMMANDS
40
- end
41
-
42
- # Get the sub-command and its options
43
- #
44
- @cmd = ARGV.shift || ''
45
- @options = case( cmd )
46
- when "restart"
47
- Trollop::options do
48
- opt :config, "The path for the config file", :type => String, :short => '-c', :default => DEFAULT_CONFIG_PATH
49
- opt :log_level, "The log level", :type => String, :default => 'info'
50
- opt :log, "The path for the log file", :type => String, :short => '-l', :default => DEFAULT_LOG_PATH
51
- opt :pid, "The path for the PID file", :type => String, :default => DEFAULT_PID_PATH
52
- opt :threads, "The number of threads", :type => Integer, :short => '-t'
53
- end
54
- when "start"
55
- Trollop::options do
56
- opt :config, "The path for the config file", :type => String, :short => '-c', :default => DEFAULT_CONFIG_PATH
57
- opt :interactive, "Execute the server in interactive mode", :short => '-i'
58
- opt :log_level, "The log level", :type => String, :default => 'info'
59
- opt :log, "The path for the log file", :type => String, :short => '-l', :default => DEFAULT_LOG_PATH
60
- opt :pid, "The path for the PID file", :type => String, :default => DEFAULT_PID_PATH
61
- opt :threads, "The number of threads", :type => Integer, :short => '-t'
62
- end
63
- when "status"
64
- Trollop::options do
65
- opt :pid, "The path for the PID file", :type => String, :default => DEFAULT_PID_PATH
66
- opt :quiet, "Do not prompt to remove an old PID file", :type => :boolean, :default => false, :short => '-q'
67
- end
68
- when "stop"
69
- Trollop::options do
70
- opt :pid, "The path for the PID file", :type => String, :default => DEFAULT_PID_PATH
71
- opt :quiet, "Do not prompt to remove an old PID file", :type => :boolean, :default => false, :short => '-q'
72
- end
73
- else
74
- Trollop::die "unknown command #{cmd.inspect}"
75
- end
76
-
77
- if cmd == 'start'
78
- unless options[:interactive]
79
- Trollop::die( :config, "is required when running as daemon" ) unless options[:config]
80
- Trollop::die( :log, "is required when running as daemon" ) unless options[:log]
81
- Trollop::die( :pid, "is required when running as daemon" ) unless options[:pid]
82
- end
83
- end
84
-
85
- if %w(restart status stop).include?( cmd )
86
- Trollop::die( :pid, "is required" ) unless options[:pid]
87
- end
88
- end
89
-
90
- def run
91
- send( cmd )
92
- end
93
-
94
- protected
95
-
96
- def start
97
- if options[:interactive]
98
- start_interactive
99
- else
100
- start_daemon
8
+ def configuration_class
9
+ RabbitWQ::Configuration
101
10
  end
102
- end
103
-
104
- def start_interactive
105
- server = RabbitWQ::Server.new( options.merge( log: nil ))
106
- server.start
107
- end
108
-
109
- def start_daemon
110
- server = RabbitWQ::ServerDaemon.new( options )
111
- server.start
112
- end
113
-
114
- def stop
115
- server = RabbitWQ::ServerDaemon.new( options )
116
- server.stop
117
- end
118
-
119
- def restart
120
- stop
121
- start_daemon
122
- end
123
11
 
124
- def status
125
- result = RabbitWQ::ServerDaemon.new( options ).status
126
- at_exit { exit result }
127
12
  end
128
13
 
129
14
  end
@@ -1,83 +1,28 @@
1
- require 'oj'
1
+ require 'servitude'
2
2
 
3
3
  module RabbitWQ
4
- class Configuration
5
-
6
- def self.attributes
7
- %w(
8
- delayed_exchange_prefix
9
- delayed_queue_prefix
10
- environment_file_path
11
- env
12
- error_queue
13
- threads
14
- time_zone
15
- work_exchange
16
- work_exchange_type
17
- work_log_level
18
- work_log_path
19
- work_publish_queue
20
- work_subscribe_queue
21
- )
22
- end
23
-
24
- attr_accessor( *attributes )
25
-
26
- def self.from_file( file_path )
27
- options = Oj.load( File.read( file_path ))
28
- RabbitWQ.configuration = Configuration.new
29
-
30
- attributes.each do |c|
31
- if options[c]
32
- RabbitWQ.configuration.send( :"#{c}=", options[c] )
33
- end
34
- end
35
- end
36
-
37
- def delayed_exchange_prefix
38
- @delayed_exchange_prefix || 'work-delay'
39
- end
40
-
41
- def delayed_queue_prefix
42
- @delayed_queue_prefix || 'work-delay'
43
- end
44
-
45
- def env
46
- @env || 'production'
47
- end
48
-
49
- def error_queue
50
- @error_queue || 'work-error'
51
- end
52
-
53
- def time_zone
54
- @time_zone || 'UTC'
55
- end
56
-
57
- def work_exchange
58
- @work_exchange || 'work'
59
- end
60
-
61
- def work_exchange_type
62
- @work_exchange_type || 'fanout'
63
- end
64
-
65
- def work_log_level
66
- @work_log_level || 'info'
67
- end
68
-
69
- def work_log_path
70
- @work_log_path || '/var/log/rabbit-wq/rabbit-wq-work.log'
71
- end
72
-
73
- def work_publish_queue
74
- @work_publish_queue || 'work'
75
- end
76
-
77
- def work_subscribe_queue
78
- @work_subscribe_queue || 'work'
4
+ class Configuration < Servitude::Configuration
5
+
6
+ def self.defaults
7
+ {
8
+ delayed_exchange_prefix: 'work-delay',
9
+ delayed_queue_prefix: 'work-delay',
10
+ env: 'production',
11
+ error_queue: 'work-error',
12
+ log: "/var/log/rabbit-wq/#{RabbitWQ.process_name}.log",
13
+ log_level: 'info',
14
+ pid: "/var/run/rabbit-wq/#{RabbitWQ.process_name}.pid",
15
+ supervision_retry_timeout_in_seconds: 1,
16
+ threads: 1,
17
+ time_zone: 'UTC',
18
+ work_exchange: 'work',
19
+ work_exchange_type: 'fanout',
20
+ work_log_level: 'info',
21
+ work_log_path: '/var/log/rabbit-wq/rabbit-wq-work.log',
22
+ work_publish_queue: 'work',
23
+ work_subscribe_queue: 'work'
24
+ }
79
25
  end
80
26
 
81
27
  end
82
-
83
28
  end
@@ -0,0 +1,5 @@
1
+ module RabbitWQ
2
+ class InvalidWorkError < StandardError
3
+
4
+ end
5
+ end
@@ -1,25 +1,27 @@
1
1
  require 'celluloid/autostart'
2
+ require 'servitude'
2
3
  require 'yaml'
3
4
 
4
5
  module RabbitWQ
5
6
  class MessageHandler
6
7
 
7
8
  include Celluloid
8
- include Logging
9
9
  include Queues
10
+ include Servitude::Logging
11
+ include WorkLogging
10
12
 
11
13
  REQUEUE = true
12
14
 
13
15
  def call( options )
14
- Time.zone = RabbitWQ.configuration.time_zone
16
+ Time.zone = Servitude.configuration.time_zone
15
17
 
16
18
  channel = options[:channel]
17
19
  delivery_info = options[:delivery_info]
18
20
  metadata = options[:metadata]
19
21
  payload = options[:payload]
20
22
 
21
- worker = YAML::load( payload )
22
- info ANSI.yellow { "WORKER [#{worker.object_id}] " + worker.inspect }
23
+ worker = deserialize_worker( payload )
24
+ info Rainbow( "WORKER [#{worker.object_id}] " + worker.inspect ).yellow
23
25
  handle_work( worker, payload )
24
26
  try_on_success_callback( worker )
25
27
  channel.ack delivery_info.delivery_tag
@@ -29,6 +31,18 @@ module RabbitWQ
29
31
 
30
32
  protected
31
33
 
34
+ def deserialize_worker( payload )
35
+ YAML::load( payload ).tap do |worker|
36
+ unless worker.is_a?( RabbitWQ::Worker )
37
+ raise ArgumentError, "Worker of type #{worker.class.name} is not a valid worker (not a descendent of #{RabbitWQ::Worker.name})"
38
+ end
39
+ end
40
+ rescue => e
41
+ raise RabbitWQ::InvalidWorkError,
42
+ "#{e.message} -- #{e.class.name}",
43
+ e.backtrace
44
+ end
45
+
32
46
  def handle_work( worker, payload )
33
47
  unless worker.enabled?
34
48
  if worker.error_on_disabled?
@@ -106,7 +120,7 @@ module RabbitWQ
106
120
  end
107
121
 
108
122
  def requeue( channel, delivery_info, e=nil )
109
- info ANSI.yellow { 'REQUEUE ' + e.message }
123
+ info Rainbow( 'REQUEUE ' + e.message ).yellow
110
124
  channel.reject delivery_info.delivery_tag, REQUEUE
111
125
  end
112
126
 
@@ -1,37 +1,42 @@
1
1
  require 'bunny'
2
- require 'celluloid/autostart'
3
2
 
4
3
  module RabbitWQ
5
4
  class Server
6
5
 
7
- include Logging
6
+ include Servitude::Server
7
+ include Servitude::ServerThreaded
8
8
  include Queues
9
- include ServerLogging
10
9
 
11
- attr_reader :options,
12
- :work_consumer,
10
+ after_initialize :initialize_work_logger
11
+ after_initialize :load_environment
12
+
13
+ attr_reader :work_consumer,
13
14
  :work_exchange
14
15
 
15
- def initialize( options )
16
- @options = options
16
+ finalize do
17
+ info 'Shutting down ...'
17
18
 
18
- configure_server
19
+ work_consumer.cancel
20
+ mq.close
19
21
  end
20
22
 
21
- def start
22
- log_startup
23
- run
23
+ protected
24
24
 
25
- trap( INT ) { finalize; exit }
26
- sleep
25
+ def handler_class
26
+ RabbitWQ::MessageHandler
27
27
  end
28
28
 
29
- protected
29
+ def run
30
+ @work_consumer = work_subscribe_queue.subscribe( manual_ack: true ) do |delivery_info, metadata, payload|
31
+ with_supervision( delivery_info: delivery_info ) do
32
+ debug( "#{Rainbow( "LISTENER RECEIVED " ).magenta} #{payload}" )
30
33
 
31
- def finalize
32
- info "SHUTTING DOWN"
33
- work_consumer.cancel
34
- mq.close
34
+ call_handler_respecting_thread_count( payload: payload,
35
+ delivery_info: delivery_info,
36
+ metadata: metadata,
37
+ channel: channel )
38
+ end
39
+ end
35
40
  end
36
41
 
37
42
  def work_exchange
@@ -45,56 +50,38 @@ module RabbitWQ
45
50
  bind( work_exchange )
46
51
  end
47
52
 
48
- def pool
49
- @pool ||= MessageHandler.pool( size: threads )
53
+ def error_queue
54
+ channel.queue( config.error_queue, durable: true )
50
55
  end
51
56
 
52
- def run
53
- if threads == 1
54
- Celluloid::Actor[:message_handler] = MessageHandler.new
55
- end
56
-
57
- @work_consumer = work_subscribe_queue.subscribe( manual_ack: true ) do |delivery_info, metadata, payload|
58
- info "LISTENER RECEIVED #{payload}"
59
-
60
- if threads > 1
61
- pool.async.call( payload: payload,
62
- delivery_info: delivery_info,
63
- metadata: metadata,
64
- channel: channel )
65
- else
66
- message_handler.call( payload: payload,
67
- delivery_info: delivery_info,
68
- metadata: metadata,
69
- channel: channel )
70
- end
71
- end
72
- end
73
-
74
- def message_handler
75
- Celluloid::Actor[:message_handler]
57
+ def warn_for_supevision_error
58
+ warn( Rainbow( "RETRYING due to waiting on supervisor to restart actor ..." ).cyan )
76
59
  end
77
60
 
78
- def threads
79
- config.threads
61
+ def warn_for_dead_actor_error
62
+ warn( Rainbow( "RETRYING due to Celluloid::DeadActorError ..." ).blue )
80
63
  end
81
64
 
82
- def config
83
- RabbitWQ.configuration
65
+ def log_error( e )
66
+ parts = [Rainbow( [e.class.name, e.message].join( ': ' ) ).red, format_backtrace( e.backtrace )]
67
+ error( parts.join( "\n" ))
84
68
  end
85
69
 
86
- def configure_server
87
- load_configuration
88
- initialize_loggers
89
- load_environment
90
- resolve_threads
70
+ def handle_error( options, e )
71
+ delivery_info = options[:delivery_info]
72
+ log_error( e )
73
+ #error_queue.publish( payload, headers: { exception_message: e.message,
74
+ #exception_class: e.class.name,
75
+ #exception_backtrace: e.backtrace } )
76
+ debug( Rainbow( "NACK" ).red + " #{e.message}" )
77
+ channel.nack( delivery_info.delivery_tag )
78
+ rescue => ex
79
+ error( Rainbow( "ERROR while handling error | #{ex.class.name} | #{ex.message} | #{ex.backtrace.inspect}" ).red )
91
80
  end
92
81
 
93
- def load_configuration
94
- if File.exists?( options[:config] )
95
- options[:config_loaded] = true
96
- Configuration.from_file( options[:config] )
97
- end
82
+ def initialize_work_logger
83
+ RabbitWQ.work_logger = WorkLogger.new( config.work_log_level,
84
+ config.work_log_path )
98
85
  end
99
86
 
100
87
  def load_environment
@@ -107,18 +94,8 @@ module RabbitWQ
107
94
  require environment_file_path
108
95
  end
109
96
 
110
- def resolve_threads
111
- if options[:threads]
112
- RabbitWQ.configuration.threads = options[:threads]
113
- end
114
-
115
- return if RabbitWQ.configuration.threads
116
-
117
- RabbitWQ.configuration.threads = 1
118
- end
119
-
120
97
  def environment_file_path
121
- RabbitWQ.configuration.environment_file_path
98
+ config.environment_file_path
122
99
  end
123
100
 
124
101
  end
@@ -1,3 +1,3 @@
1
1
  module RabbitWQ
2
- VERSION = "1.9.0"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -5,6 +5,10 @@ module RabbitWQ
5
5
 
6
6
  YAML_MIMETYPE = 'application/yaml'
7
7
 
8
+ def self.config
9
+ Servitude.configuration ||= RabbitWQ::Configuration.load
10
+ end
11
+
8
12
  def self.enqueue( worker, options={} )
9
13
  payload = worker.to_yaml
10
14
  enqueue_payload( payload, options )
@@ -82,9 +86,5 @@ module RabbitWQ
82
86
  end
83
87
  end
84
88
 
85
- def self.config
86
- RabbitWQ.configuration
87
- end
88
-
89
89
  end
90
90
  end
@@ -32,7 +32,7 @@ module RabbitWQ
32
32
  end
33
33
 
34
34
  if worker
35
- logger.send( level, "[" + ANSI.cyan { "#{worker.class.name}:#{worker.object_id}" } + "] #{message}" )
35
+ logger.send( level, "[" + Rainbow( "#{worker.class.name}:#{worker.object_id}" ).cyan + "] #{message}" )
36
36
  else
37
37
  logger.send( level, message )
38
38
  end
@@ -1,7 +1,7 @@
1
1
  require 'yell'
2
2
 
3
3
  module RabbitWQ
4
- module Logging
4
+ module WorkLogging
5
5
 
6
6
  %w(
7
7
  debug
@@ -11,13 +11,6 @@ module RabbitWQ
11
11
  warn
12
12
  ).each do |level|
13
13
 
14
- define_method level do |*messages|
15
- return unless RabbitWQ.logger
16
- messages.each do |message|
17
- RabbitWQ.logger.send level, message
18
- end
19
- end
20
-
21
14
  define_method "worker_#{level}" do |worker, *messages|
22
15
  return unless RabbitWQ.work_logger
23
16
  messages.each do |message|
data/lib/rabbit_wq.rb CHANGED
@@ -1,41 +1,46 @@
1
- require 'ansi'
1
+ require 'rainbow'
2
+ require 'servitude'
2
3
  require 'rabbit_wq/version'
3
4
 
4
5
  module RabbitWQ
5
6
 
6
- APP_ID = 'rabbit-wq'
7
- APP_NAME = 'Rabbit Work Queue'
8
- INT = 'INT'
9
- VERSION_COPYRIGHT = "v#{VERSION} \u00A9#{Time.now.year}"
10
-
11
- autoload :Command, 'rabbit_wq/command'
12
- autoload :Configuration, 'rabbit_wq/configuration'
13
- autoload :FinalError, 'rabbit_wq/final_error'
14
- autoload :Logging, 'rabbit_wq/logging'
15
- autoload :Queues, 'rabbit_wq/queues'
16
- autoload :MessageHandler, 'rabbit_wq/message_handler'
17
- autoload :Server, 'rabbit_wq/server'
18
- autoload :ServerDaemon, 'rabbit_wq/server_daemon'
19
- autoload :ServerLogging, 'rabbit_wq/server_logging'
20
- autoload :Work, 'rabbit_wq/work'
21
- autoload :Worker, 'rabbit_wq/worker'
22
- autoload :WorkLogger, 'rabbit_wq/work_logger'
23
-
24
- def self.configuration
25
- @configuration ||= Configuration.new
7
+ include Servitude::Base
8
+
9
+ autoload :Command, 'rabbit_wq/command'
10
+ autoload :Cli, 'rabbit_wq/cli'
11
+ autoload :Configuration, 'rabbit_wq/configuration'
12
+ autoload :FinalError, 'rabbit_wq/final_error'
13
+ autoload :InvalidWorkError, 'rabbit_wq/invalid_work_error'
14
+ autoload :Queues, 'rabbit_wq/queues'
15
+ autoload :MessageHandler, 'rabbit_wq/message_handler'
16
+ autoload :Server, 'rabbit_wq/server'
17
+ autoload :Work, 'rabbit_wq/work'
18
+ autoload :Worker, 'rabbit_wq/worker'
19
+ autoload :WorkLogger, 'rabbit_wq/work_logger'
20
+ autoload :WorkLogging, 'rabbit_wq/work_logging'
21
+
22
+ def self.perform_boot
23
+ author = 'C. Jason Harrelson'
24
+
25
+ years = 2013
26
+ years = "#{years}–#{::Time.now.year}" if years < ::Time.now.year
27
+
28
+ boot host_namespace: self,
29
+ app_name: 'Rabbit WQ',
30
+ author: author,
31
+ attribution: "v#{VERSION} Copyright © #{years} #{author}",
32
+ default_config_path: "/etc/rabbit-wq/#{process_name}.conf",
33
+ use_config: true
26
34
  end
27
35
 
28
- def self.configuration=( configuration )
29
- @configuration = configuration
30
- end
31
-
32
- def self.configure
33
- yield( configuration ) if block_given?
36
+ def self.process_name
37
+ 'rabbit-wq'
34
38
  end
35
39
 
36
40
  class << self
37
- attr_accessor :logger,
38
- :work_logger
41
+ attr_accessor :work_logger
39
42
  end
40
43
 
44
+ perform_boot
45
+
41
46
  end
data/rabbit-wq.gemspec CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency "bunny", "~> 1"
25
25
  spec.add_dependency "celluloid", "~> 0"
26
26
  spec.add_dependency "oj", "~> 2"
27
- spec.add_dependency "trollop", "~> 2"
27
+ spec.add_dependency "servitude", ">= 1.2", "< 2"
28
28
  spec.add_dependency "yell", "~> 1"
29
29
 
30
30
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rabbit-wq
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - C. Jason Harrelson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-09 00:00:00.000000000 Z
11
+ date: 2015-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -81,17 +81,23 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '2'
83
83
  - !ruby/object:Gem::Dependency
84
- name: trollop
84
+ name: servitude
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '1.2'
90
+ - - "<"
88
91
  - !ruby/object:Gem::Version
89
92
  version: '2'
90
93
  type: :runtime
91
94
  prerelease: false
92
95
  version_requirements: !ruby/object:Gem::Requirement
93
96
  requirements:
94
- - - "~>"
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '1.2'
100
+ - - "<"
95
101
  - !ruby/object:Gem::Version
96
102
  version: '2'
97
103
  - !ruby/object:Gem::Dependency
@@ -124,22 +130,20 @@ files:
124
130
  - README.md
125
131
  - Rakefile
126
132
  - bin/rabbit-wq
127
- - lib/ansi.rb
128
133
  - lib/rabbit-wq.rb
129
134
  - lib/rabbit_wq.rb
130
135
  - lib/rabbit_wq/cli.rb
131
136
  - lib/rabbit_wq/command.rb
132
137
  - lib/rabbit_wq/configuration.rb
133
138
  - lib/rabbit_wq/final_error.rb
134
- - lib/rabbit_wq/logging.rb
139
+ - lib/rabbit_wq/invalid_work_error.rb
135
140
  - lib/rabbit_wq/message_handler.rb
136
141
  - lib/rabbit_wq/queues.rb
137
142
  - lib/rabbit_wq/server.rb
138
- - lib/rabbit_wq/server_daemon.rb
139
- - lib/rabbit_wq/server_logging.rb
140
143
  - lib/rabbit_wq/version.rb
141
144
  - lib/rabbit_wq/work.rb
142
145
  - lib/rabbit_wq/work_logger.rb
146
+ - lib/rabbit_wq/work_logging.rb
143
147
  - lib/rabbit_wq/worker.rb
144
148
  - rabbit-wq.gemspec
145
149
  homepage: ''
data/lib/ansi.rb DELETED
@@ -1,36 +0,0 @@
1
- class ANSI
2
-
3
- def self.resolve_text( color, &block )
4
- text = nil
5
- if block_given?
6
- text = block.call + reset
7
- end
8
- "\e[#{chart[color.to_sym]}m#{text}"
9
- end
10
-
11
- def self.reset
12
- "\e[0m"
13
- end
14
-
15
- def self.chart
16
- {
17
- black: 30,
18
- red: 31,
19
- green: 32,
20
- yellow: 33,
21
- blue: 34,
22
- magenta: 35,
23
- cyan: 36,
24
- white: 37
25
- }
26
- end
27
-
28
- chart.keys.each do |color|
29
-
30
- define_singleton_method color do |&block|
31
- resolve_text color, &block
32
- end
33
-
34
- end
35
-
36
- end
@@ -1,149 +0,0 @@
1
- require 'rubygems'
2
- require 'fileutils'
3
- require 'timeout'
4
-
5
- module RabbitWQ
6
- class ServerDaemon
7
-
8
- attr_reader :name,
9
- :options,
10
- :pid,
11
- :pid_path,
12
- :script,
13
- :timeout
14
-
15
- def initialize( options )
16
- @options = options
17
- @name = options[:name] || APP_NAME
18
- @pid_path = options[:pid] || '.'
19
- @pid = get_pid
20
- @timeout = options[:timeout] || 10
21
- end
22
-
23
- def start
24
- abort "Process already running!" if process_exists?
25
-
26
- pid = fork do
27
- exit if fork
28
- Process.setsid
29
- exit if fork
30
- store_pid( Process.pid )
31
- File.umask 0000
32
- redirect_output!
33
- run
34
- end
35
-
36
- Process.waitpid( pid )
37
- end
38
-
39
- def run
40
- Server.new( options ).start
41
- end
42
-
43
- def stop
44
- kill_process
45
- FileUtils.rm pid_path
46
- end
47
-
48
- def status
49
- $stdout.print "#{APP_NAME} "
50
- if process_exists?
51
- $stdout.puts "process running with PID: #{pid}"
52
- true
53
- else
54
- $stdout.puts "process does not exist"
55
- false
56
- end
57
- end
58
-
59
- protected
60
-
61
- #def create_pid( pid )
62
- def store_pid( pid )
63
- File.open( pid_path, 'w' ) do |f|
64
- f.puts pid
65
- end
66
- rescue => e
67
- $stderr.puts "Unable to open #{pid_path} for writing:\n\t(#{e.class}) #{e.message}"
68
- exit!
69
- end
70
-
71
- def get_pid
72
- return nil unless File.exists?( pid_path )
73
- pid = nil
74
- File.open( @pid_path, 'r' ) do |f|
75
- pid = f.readline.to_s.gsub( /[^0-9]/, '' )
76
- end
77
- pid.to_i
78
- rescue Errno::ENOENT
79
- nil
80
- end
81
-
82
- def remove_pidfile
83
- File.unlink( pid_path )
84
- rescue => e
85
- $stderr.puts "Unable to unlink #{pid_path}:\n\t(#{e.class}) #{e.message}"
86
- exit
87
- end
88
-
89
- def kill_process
90
- unless process_exists?
91
- $stdout.write "#{APP_NAME} process is not running"
92
- return
93
- end
94
-
95
- $stdout.write "Attempting to stop #{APP_NAME} process #{pid}..."
96
- Process.kill INT, pid
97
- iteration_num = 0
98
- while process_exists? && iteration_num < 10
99
- sleep 1
100
- $stdout.write "."
101
- iteration_num += 1
102
- end
103
- if process_exists?
104
- $stderr.puts "\nFailed to stop #{APP_NAME} process #{pid}"
105
- else
106
- $stdout.puts "\nSuccessfuly stopped #{APP_NAME} process #{pid}"
107
- end
108
- rescue Errno::EPERM
109
- $stderr.puts "No permission to query #{pid}!";
110
- end
111
-
112
- def process_exists?
113
- return false unless pid
114
- Process.kill( 0, pid )
115
- true
116
- rescue Errno::ESRCH, TypeError # "PID is NOT running or is zombied
117
- false
118
- rescue Errno::EPERM
119
- $stderr.puts "No permission to query #{pid}!";
120
- false
121
- end
122
-
123
- def redirect_output!
124
- if log_path = options[:log]
125
- #puts "redirecting to log"
126
- # if the log directory doesn't exist, create it
127
- FileUtils.mkdir_p( File.dirname( log_path ), :mode => 0755 )
128
- # touch the log file to create it
129
- FileUtils.touch( log_path )
130
- # Set permissions on the log file
131
- File.chmod( 0644, log_path )
132
- # Reopen $stdout (NOT +STDOUT+) to start writing to the log file
133
- $stdout.reopen( log_path, 'a' )
134
- # Redirect $stderr to $stdout
135
- $stderr.reopen $stdout
136
- $stdout.sync = true
137
- else
138
- #puts "redirecting to /dev/null"
139
- # We're not bothering to sync if we're dumping to /dev/null
140
- # because /dev/null doesn't care about buffered output
141
- $stdin.reopen '/dev/null'
142
- $stdout.reopen '/dev/null', 'a'
143
- $stderr.reopen $stdout
144
- end
145
- log_path = options[:log] ? options[:log] : '/dev/null'
146
- end
147
-
148
- end
149
- end
@@ -1,52 +0,0 @@
1
- require 'yell'
2
-
3
- # Provides logging services for the base server.
4
- #
5
- module RabbitWQ
6
- module ServerLogging
7
-
8
- protected
9
-
10
- def initialize_loggers
11
- RabbitWQ.logger = Yell.new do |l|
12
- l.level = log_level
13
- l.adapter $stdout, :level => [:debug, :info, :warn]
14
- l.adapter $stderr, :level => [:error, :fatal]
15
- end
16
-
17
- RabbitWQ.work_logger = WorkLogger.new( RabbitWQ.configuration.work_log_level,
18
- RabbitWQ.configuration.work_log_path )
19
- #Celluloid.logger = Yell.new do |l|
20
- #l.level = :info
21
- #l.adapter :file, File.join( File.dirname( options[:log] ), "#{APP_ID}-celluloid.log" )
22
- #end
23
- end
24
-
25
- def log_startup
26
- start_banner( options ).each do |line|
27
- RabbitWQ.logger.info line
28
- end
29
- end
30
-
31
- def start_banner( options )
32
- [
33
- "",
34
- "***",
35
- "* #{APP_NAME} started",
36
- "*",
37
- "* #{VERSION_COPYRIGHT}",
38
- "*",
39
- "* Configuration:",
40
- (options[:config_loaded] ? "* file: #{options[:config]}" : nil),
41
- RabbitWQ::Configuration.attributes.map { |a| "* #{a}: #{RabbitWQ.configuration.send( a )}" },
42
- "*",
43
- "***",
44
- ].flatten.reject( &:nil? )
45
- end
46
-
47
- def log_level
48
- options.fetch( :log_level, :info ).to_sym
49
- end
50
-
51
- end
52
- end