rabbit-wq 1.9.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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