rabbit_jobs 0.7.8 → 0.7.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/lib/rabbit_jobs/amqp_helper.rb +1 -3
- data/lib/rabbit_jobs/configuration.rb +18 -32
- data/lib/rabbit_jobs/consumer/job_consumer.rb +22 -1
- data/lib/rabbit_jobs/error_mailer.rb +36 -24
- data/lib/rabbit_jobs/job.rb +111 -103
- data/lib/rabbit_jobs/main_loop.rb +40 -0
- data/lib/rabbit_jobs/publisher.rb +24 -37
- data/lib/rabbit_jobs/scheduler.rb +34 -64
- data/lib/rabbit_jobs/tasks.rb +0 -2
- data/lib/rabbit_jobs/version.rb +1 -1
- data/lib/rabbit_jobs/worker.rb +45 -68
- data/lib/rabbit_jobs.rb +13 -3
- data/spec/fixtures/config.yml +0 -1
- data/spec/fixtures/jobs.rb +6 -1
- data/spec/integration/publisher_spec.rb +2 -2
- data/spec/integration/worker_spec.rb +12 -8
- data/spec/spec_helper.rb +8 -0
- data/spec/unit/configuration_spec.rb +3 -9
- data/spec/unit/worker_spec.rb +14 -19
- metadata +13 -12
@@ -1,6 +1,4 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
require 'bunny'
|
3
|
-
require 'uri'
|
4
2
|
|
5
3
|
module RabbitJobs
|
6
4
|
class AmqpHelper
|
@@ -8,7 +6,7 @@ module RabbitJobs
|
|
8
6
|
class << self
|
9
7
|
|
10
8
|
def prepare_connection
|
11
|
-
conn = Bunny.new(
|
9
|
+
conn = Bunny.new(RabbitJobs.config.server, :heartbeat_interval => 5)
|
12
10
|
conn.start unless conn.connected? || conn.connecting?
|
13
11
|
conn
|
14
12
|
end
|
@@ -1,7 +1,4 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
require 'yaml'
|
3
|
-
require 'uri'
|
4
|
-
|
5
2
|
module RabbitJobs
|
6
3
|
|
7
4
|
extend self
|
@@ -28,7 +25,7 @@ module RabbitJobs
|
|
28
25
|
|
29
26
|
unless @@configuration
|
30
27
|
self.configure do |c|
|
31
|
-
c.
|
28
|
+
c.server "amqp://localhost"
|
32
29
|
end
|
33
30
|
end
|
34
31
|
|
@@ -63,8 +60,7 @@ module RabbitJobs
|
|
63
60
|
def initialize
|
64
61
|
@data = {
|
65
62
|
error_log: true,
|
66
|
-
server: 'amqp://localhost
|
67
|
-
prefix: 'rabbit_jobs',
|
63
|
+
server: 'amqp://localhost',
|
68
64
|
queues: {}
|
69
65
|
}
|
70
66
|
end
|
@@ -102,15 +98,6 @@ module RabbitJobs
|
|
102
98
|
@data[:server]
|
103
99
|
end
|
104
100
|
|
105
|
-
def prefix(value = nil)
|
106
|
-
if value
|
107
|
-
raise ArgumentError unless value.is_a?(String) && value != ""
|
108
|
-
@data[:prefix] = value.downcase
|
109
|
-
else
|
110
|
-
@data[:prefix]
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
101
|
def queue(name, params = {})
|
115
102
|
raise ArgumentError.new("name is #{name.inspect}") unless name && name.is_a?(String) && name != ""
|
116
103
|
raise ArgumentError.new("params is #{params.inspect}") unless params && params.is_a?(Hash)
|
@@ -128,11 +115,6 @@ module RabbitJobs
|
|
128
115
|
@data[:queues].keys
|
129
116
|
end
|
130
117
|
|
131
|
-
def queue_name(routing_key)
|
132
|
-
routing_key = routing_key.to_sym
|
133
|
-
@data[:queues][routing_key][:ignore_prefix] ? routing_key : [@data[:prefix], routing_key].compact.join('#')
|
134
|
-
end
|
135
|
-
|
136
118
|
def load_file(filename)
|
137
119
|
load_yaml(File.read(filename))
|
138
120
|
end
|
@@ -142,19 +124,23 @@ module RabbitJobs
|
|
142
124
|
end
|
143
125
|
|
144
126
|
def convert_yaml_config(yaml)
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
end
|
154
|
-
yaml['queues'].each do |name, params|
|
155
|
-
queue name, symbolize_keys!(params) || {}
|
156
|
-
end
|
127
|
+
yaml = parse_environment(yaml)
|
128
|
+
|
129
|
+
@data = {queues: {}}
|
130
|
+
%w(server mail_errors_to mail_errors_from).each do |m|
|
131
|
+
self.send(m, yaml[m])
|
132
|
+
end
|
133
|
+
yaml['queues'].each do |name, params|
|
134
|
+
queue name, symbolize_keys!(params) || {}
|
157
135
|
end
|
158
136
|
end
|
137
|
+
|
138
|
+
private
|
139
|
+
|
140
|
+
def parse_environment(yaml)
|
141
|
+
yaml['rabbit_jobs'] ||
|
142
|
+
(defined?(Rails) && yaml[Rails.env.to_s]) ||
|
143
|
+
yaml
|
144
|
+
end
|
159
145
|
end
|
160
146
|
end
|
@@ -3,9 +3,10 @@ module RabbitJobs
|
|
3
3
|
module Consumer
|
4
4
|
class JobConsumer
|
5
5
|
def process_message(delivery_info, properties, payload)
|
6
|
-
job = RJ::Job.parse(payload)
|
6
|
+
job, *error_args = RJ::Job.parse(payload)
|
7
7
|
|
8
8
|
if job.is_a?(Symbol)
|
9
|
+
report_error(job, *error_args)
|
9
10
|
# case @job
|
10
11
|
# when :not_found
|
11
12
|
# when :parsing_error
|
@@ -23,5 +24,25 @@ module RabbitJobs
|
|
23
24
|
true
|
24
25
|
end
|
25
26
|
end
|
27
|
+
|
28
|
+
def log_error(msg)
|
29
|
+
RJ.logger.error msg
|
30
|
+
end
|
31
|
+
|
32
|
+
def report_error(error_type, *args)
|
33
|
+
case error_type
|
34
|
+
when :not_found
|
35
|
+
log_error "Cannot find job class '#{args.first}'"
|
36
|
+
when :parsing_error
|
37
|
+
log_error "Cannot initialize job. Json parsing error."
|
38
|
+
log_error "Data received: #{args.first.inspect}"
|
39
|
+
when :error
|
40
|
+
ex, payload = args
|
41
|
+
log_error "Cannot initialize job."
|
42
|
+
log_error ex.message
|
43
|
+
log_error _cleanup_backtrace(ex.backtrace).join("\n")
|
44
|
+
log_error "Data received: #{payload.inspect}"
|
45
|
+
end
|
46
|
+
end
|
26
47
|
end
|
27
48
|
end
|
@@ -1,35 +1,47 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
module RabbitJobs
|
3
3
|
class ErrorMailer
|
4
|
-
|
5
|
-
|
6
|
-
defined?(ActionMailer) &&
|
7
|
-
|
8
|
-
|
9
|
-
)
|
10
|
-
|
4
|
+
class << self
|
5
|
+
def enabled?
|
6
|
+
defined?(ActionMailer) && config_present?
|
7
|
+
end
|
8
|
+
|
9
|
+
def send_letter(subject, body)
|
10
|
+
letter = ActionMailer::Base.mail
|
11
|
+
letter.from = RabbitJobs.config.mail_errors_from
|
12
|
+
letter.to = RabbitJobs.config.mail_errors_to
|
13
|
+
letter.subject = subject
|
14
|
+
letter.body = body
|
15
|
+
|
16
|
+
letter.deliver
|
17
|
+
end
|
11
18
|
|
12
|
-
|
13
|
-
|
19
|
+
def report_error(job, error = $!)
|
20
|
+
return unless enabled?
|
14
21
|
|
15
|
-
|
22
|
+
begin
|
23
|
+
subject, text = build_error_message(job, error)
|
24
|
+
send_letter(subject, text)
|
25
|
+
rescue
|
26
|
+
RabbitJobs.logger.error [$!.message, $!.backtrace].flatten.join("\n")
|
27
|
+
end
|
28
|
+
end
|
16
29
|
|
17
|
-
|
18
|
-
subject = "RJ:Worker: #{error.class} on #{job.class}"
|
19
|
-
text = "\n#{job.class}.perform(#{params_str})\n"
|
20
|
-
text += "\n#{error.inspect}\n"
|
21
|
-
text += "\nBacktrace:\n#{error.backtrace.join("\n")}" if error.backtrace
|
30
|
+
private
|
22
31
|
|
23
|
-
|
24
|
-
|
25
|
-
letter.to = RabbitJobs.config.mail_errors_to
|
26
|
-
letter.subject = subject
|
27
|
-
letter.body = text
|
32
|
+
def build_error_message(job, error)
|
33
|
+
params = job.params || []
|
28
34
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
35
|
+
params_str = params.map { |p| p.inspect }.join(', ')
|
36
|
+
subject = "RJ:Worker: #{error.class} on #{job.class}"
|
37
|
+
text = "\n#{job.class}.perform(#{params_str})\n"
|
38
|
+
text += "\n#{error.inspect}\n"
|
39
|
+
text += "\nBacktrace:\n#{error.backtrace.join("\n")}" if error.backtrace
|
40
|
+
end
|
41
|
+
|
42
|
+
def config_present?
|
43
|
+
config = RabbitJobs.config
|
44
|
+
config.mail_errors_from.present? && config.mail_errors_to.present?
|
33
45
|
end
|
34
46
|
end
|
35
47
|
end
|
data/lib/rabbit_jobs/job.rb
CHANGED
@@ -1,130 +1,138 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
|
3
|
-
|
2
|
+
module RabbitJobs
|
3
|
+
module Job
|
4
|
+
include RabbitJobs::Helpers
|
5
|
+
extend self
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
extend self
|
7
|
+
def self.included(base)
|
8
|
+
base.extend (ClassMethods)
|
8
9
|
|
9
|
-
|
10
|
-
|
10
|
+
def initialize(*perform_params)
|
11
|
+
self.params = perform_params
|
12
|
+
self.opts = {}
|
13
|
+
end
|
11
14
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
attr_accessor :params, :opts
|
16
|
+
|
17
|
+
def run_perform
|
18
|
+
begin
|
19
|
+
start_time = Time.now
|
20
|
+
RabbitJobs.logger.info "Started to perform #{self.to_ruby_string}"
|
21
|
+
self.class.perform(*params)
|
22
|
+
execution_time = Time.now - start_time
|
23
|
+
RabbitJobs.logger.info " Job completed #{self.to_ruby_string} in #{execution_time} seconds."
|
24
|
+
rescue
|
25
|
+
log_job_error($!)
|
26
|
+
run_on_error_hooks($!)
|
27
|
+
end
|
28
|
+
end
|
16
29
|
|
17
|
-
|
30
|
+
def run_on_error_hooks(error)
|
31
|
+
if self.class.rj_on_error_hooks
|
32
|
+
self.class.rj_on_error_hooks.each do |proc_or_symbol|
|
33
|
+
proc = proc_or_symbol
|
34
|
+
if proc_or_symbol.is_a?(Symbol)
|
35
|
+
proc = self.method(proc_or_symbol)
|
36
|
+
end
|
37
|
+
|
38
|
+
case proc.arity
|
39
|
+
when 0
|
40
|
+
proc.call()
|
41
|
+
when 1
|
42
|
+
proc.call(error)
|
43
|
+
else
|
44
|
+
proc.call(error, *params)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
18
49
|
|
19
|
-
|
20
|
-
|
21
|
-
start_time = Time.now
|
22
|
-
RJ.logger.info "Started to perform #{self.to_ruby_string}"
|
23
|
-
self.class.perform(*params)
|
24
|
-
execution_time = Time.now - start_time
|
25
|
-
RJ.logger.info " Job completed #{self.to_ruby_string} in #{execution_time} seconds."
|
26
|
-
rescue
|
27
|
-
RJ.logger.warn $!.message
|
28
|
-
RJ.logger.warn(self.to_ruby_string)
|
29
|
-
RJ.logger.warn _cleanup_backtrace($!.backtrace).join("\n")
|
30
|
-
run_on_error_hooks($!)
|
31
|
-
RabbitJobs::ErrorMailer.report_error(self, $!)
|
50
|
+
def payload
|
51
|
+
{'class' => self.class.to_s, 'opts' => (self.opts || {}), 'params' => params}.to_json
|
32
52
|
end
|
33
|
-
end
|
34
53
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
proc = proc_or_symbol
|
39
|
-
if proc_or_symbol.is_a?(Symbol)
|
40
|
-
proc = self.method(proc_or_symbol)
|
41
|
-
end
|
54
|
+
def expires_in
|
55
|
+
self.class.rj_expires_in
|
56
|
+
end
|
42
57
|
|
43
|
-
|
44
|
-
|
45
|
-
proc.call()
|
46
|
-
when 1
|
47
|
-
proc.call(error)
|
48
|
-
else
|
49
|
-
proc.call(error, *params)
|
50
|
-
end
|
51
|
-
end
|
58
|
+
def expires?
|
59
|
+
self.expires_in && self.expires_in > 0
|
52
60
|
end
|
53
|
-
end
|
54
61
|
|
55
|
-
|
56
|
-
|
57
|
-
|
62
|
+
def expires_at_expired?
|
63
|
+
expires_at = opts['expires_at'].to_i
|
64
|
+
return false if expires_at == 0
|
65
|
+
Time.now.to_i > expires_at
|
66
|
+
end
|
58
67
|
|
59
|
-
|
60
|
-
|
61
|
-
|
68
|
+
def expires_in_expired?
|
69
|
+
exp_in = self.expires_in.to_i
|
70
|
+
created_at = opts['created_at'].to_i
|
71
|
+
return false if exp_in == 0 || created_at == 0
|
62
72
|
|
63
|
-
|
64
|
-
|
65
|
-
end
|
73
|
+
Time.now.to_i > created_at + exp_in
|
74
|
+
end
|
66
75
|
|
67
|
-
|
68
|
-
|
69
|
-
Time.now.to_i > opts['expires_at'].to_i
|
70
|
-
elsif expires? && opts['created_at']
|
71
|
-
Time.now.to_i > (opts['created_at'].to_i + expires_in.to_i)
|
72
|
-
else
|
73
|
-
false
|
76
|
+
def expired?
|
77
|
+
expires_at_expired? || expires_in_expired?
|
74
78
|
end
|
75
|
-
end
|
76
79
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
rs <<
|
82
|
-
|
80
|
+
def to_ruby_string
|
81
|
+
rs = self.class.name
|
82
|
+
rs << params_string
|
83
|
+
if opts.count > 0
|
84
|
+
rs << ", opts: "
|
85
|
+
rs << opts.inspect
|
86
|
+
end
|
83
87
|
end
|
84
|
-
|
85
|
-
|
86
|
-
|
88
|
+
|
89
|
+
def params_string
|
90
|
+
if params.count > 0
|
91
|
+
"(#{params.map(&:to_s).join(", ")})"
|
92
|
+
else
|
93
|
+
""
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def log_job_error(error)
|
98
|
+
RabbitJobs.logger.warn error.message
|
99
|
+
RabbitJobs.logger.warn(self.to_ruby_string)
|
100
|
+
RabbitJobs.logger.warn _cleanup_backtrace(error.backtrace).join("\n")
|
101
|
+
RabbitJobs::ErrorMailer.report_error(self, error) rescue nil
|
87
102
|
end
|
88
103
|
end
|
89
|
-
end
|
90
104
|
|
91
|
-
|
92
|
-
|
105
|
+
module ClassMethods
|
106
|
+
attr_accessor :rj_expires_in, :rj_on_error_hooks
|
93
107
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
108
|
+
# DSL method for jobs
|
109
|
+
def expires_in(seconds)
|
110
|
+
@rj_expires_in = seconds.to_i
|
111
|
+
end
|
98
112
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
113
|
+
def on_error(*hooks)
|
114
|
+
hooks.each do |proc_or_symbol|
|
115
|
+
raise ArgumentError unless proc_or_symbol && ( proc_or_symbol.is_a?(Proc) || proc_or_symbol.is_a?(Symbol) )
|
116
|
+
@rj_on_error_hooks ||= []
|
117
|
+
@rj_on_error_hooks << proc_or_symbol
|
118
|
+
end
|
104
119
|
end
|
105
120
|
end
|
106
|
-
end
|
107
121
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
rescue
|
123
|
-
RJ.logger.warn "Cannot initialize job."
|
124
|
-
RJ.logger.warn $!.message
|
125
|
-
RJ.logger.warn _cleanup_backtrace($!.backtrace).join("\n")
|
126
|
-
RJ.logger.warn "Data received: #{payload.inspect}"
|
127
|
-
:error
|
122
|
+
def self.parse(payload)
|
123
|
+
begin
|
124
|
+
encoded = JSON.parse(payload)
|
125
|
+
job_klass = constantize(encoded['class'])
|
126
|
+
job = job_klass.new(*encoded['params'])
|
127
|
+
job.opts = encoded['opts']
|
128
|
+
job
|
129
|
+
rescue NameError
|
130
|
+
[:not_found, encoded['class']]
|
131
|
+
rescue JSON::ParserError
|
132
|
+
[:parsing_error, payload]
|
133
|
+
rescue
|
134
|
+
[:error, $!, payload]
|
135
|
+
end
|
128
136
|
end
|
129
137
|
end
|
130
|
-
end
|
138
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module RabbitJobs
|
3
|
+
module MainLoop
|
4
|
+
def shutdown
|
5
|
+
@shutdown = true
|
6
|
+
end
|
7
|
+
|
8
|
+
def shutdown!
|
9
|
+
shutdown
|
10
|
+
end
|
11
|
+
|
12
|
+
def main_loop(time)
|
13
|
+
while true
|
14
|
+
sleep 1
|
15
|
+
if time > 0
|
16
|
+
time -= 1
|
17
|
+
if time == 0
|
18
|
+
shutdown
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
if @shutdown
|
23
|
+
RabbitJobs.logger.info "Stopping."
|
24
|
+
yield if block_given?
|
25
|
+
return true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def log_daemon_error(error)
|
31
|
+
if RabbitJobs.logger
|
32
|
+
begin
|
33
|
+
RabbitJobs.logger.error [error.message, error.backtrace].flatten.join("\n")
|
34
|
+
ensure
|
35
|
+
abort(error.message)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,11 +1,5 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
|
3
|
-
require 'json'
|
4
|
-
require 'bunny'
|
5
|
-
require 'uri'
|
6
|
-
require 'active_support'
|
7
|
-
require 'active_support/core_ext/module'
|
8
|
-
|
9
3
|
module RabbitJobs
|
10
4
|
module Publisher
|
11
5
|
extend self
|
@@ -17,8 +11,9 @@ module RabbitJobs
|
|
17
11
|
end
|
18
12
|
|
19
13
|
def publish_to(routing_key, klass, *params)
|
20
|
-
raise ArgumentError.new("klass=#{klass.inspect}") unless klass
|
21
|
-
|
14
|
+
raise ArgumentError.new("klass=#{klass.inspect}") unless klass.is_a?(Class) || klass.is_a?(String)
|
15
|
+
routing_key = routing_key.to_sym unless routing_key.is_a?(Symbol)
|
16
|
+
raise ArgumentError.new("routing_key=#{routing_key}") unless RabbitJobs.config[:queues][routing_key]
|
22
17
|
|
23
18
|
payload = {
|
24
19
|
'class' => klass.to_s,
|
@@ -26,35 +21,43 @@ module RabbitJobs
|
|
26
21
|
'params' => params
|
27
22
|
}.to_json
|
28
23
|
|
29
|
-
direct_publish_to(
|
24
|
+
direct_publish_to(routing_key, payload)
|
30
25
|
end
|
31
26
|
|
32
27
|
def direct_publish_to(routing_key, payload, ex = {})
|
33
28
|
check_connection
|
34
29
|
begin
|
35
|
-
|
36
|
-
|
37
|
-
|
30
|
+
exchange_name = ex.delete(:name).to_s
|
31
|
+
exchange_opts = Configuration::DEFAULT_MESSAGE_PARAMS.merge(ex || {})
|
32
|
+
connection.default_channel.basic_publish(payload, exchange_name, routing_key, exchange_opts)
|
38
33
|
rescue
|
39
|
-
|
40
|
-
|
34
|
+
RabbitJobs.logger.warn $!.message
|
35
|
+
RabbitJobs.logger.warn $!.backtrace.join("\n")
|
41
36
|
raise $!
|
42
37
|
end
|
43
38
|
|
44
39
|
true
|
45
40
|
end
|
46
41
|
|
42
|
+
def queue_status(routing_key)
|
43
|
+
raise ArgumentError unless routing_key.present?
|
44
|
+
|
45
|
+
routing_key = routing_key.to_sym
|
46
|
+
queue_declare_ok = connection.default_channel.queue_declare(routing_key, RabbitJobs.config[:queues][routing_key].merge(passive: true))
|
47
|
+
{
|
48
|
+
message_count: queue_declare_ok.message_count,
|
49
|
+
consumer_count: queue_declare_ok.consumer_count
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
47
53
|
def purge_queue(*routing_keys)
|
48
|
-
raise ArgumentError unless routing_keys
|
54
|
+
raise ArgumentError unless routing_keys.present?
|
49
55
|
|
50
56
|
messages_count = 0
|
51
|
-
count = routing_keys.count
|
52
57
|
|
53
58
|
routing_keys.map(&:to_sym).each do |routing_key|
|
54
|
-
|
55
|
-
|
56
|
-
messages_count += queue.status[:message_count]
|
57
|
-
queue.purge
|
59
|
+
messages_count += queue_status(routing_key)[:message_count].to_i
|
60
|
+
connection.default_channel.queue_purge(routing_key)
|
58
61
|
end
|
59
62
|
|
60
63
|
messages_count
|
@@ -68,29 +71,13 @@ module RabbitJobs
|
|
68
71
|
|
69
72
|
def connection
|
70
73
|
unless settings[:connection]
|
71
|
-
settings[:connection] = Bunny.new(
|
74
|
+
settings[:connection] = Bunny.new(RabbitJobs.config.server, :heartbeat_interval => 5)
|
72
75
|
settings[:connection].start
|
73
76
|
# settings[:channel].confirm_select
|
74
77
|
end
|
75
78
|
settings[:connection]
|
76
79
|
end
|
77
80
|
|
78
|
-
def exchanges
|
79
|
-
settings[:exchanges] ||= {}
|
80
|
-
end
|
81
|
-
|
82
|
-
def get_exchange(ex = {})
|
83
|
-
ex = {name: ex} if ex.is_a?(String)
|
84
|
-
raise ArgumentError.new("Need to pass exchange name") if ex.size > 0 && ex[:name].to_s.empty?
|
85
|
-
|
86
|
-
if ex.size > 0
|
87
|
-
exchange_opts = Configuration::DEFAULT_EXCHANGE_PARAMS.merge(ex[:params] || {}).merge({type: (ex[:type] || :direct)})
|
88
|
-
exchanges[ex[:name]] ||= connection.default_channel.exchange(ex[:name].to_s, exchange_opts)
|
89
|
-
else
|
90
|
-
exchanges[ex[:name]] ||= connection.default_channel.default_exchange
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
81
|
def check_connection
|
95
82
|
raise unless connection.connected?
|
96
83
|
end
|
@@ -1,19 +1,20 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
|
3
|
-
require 'rufus/scheduler'
|
4
|
-
require 'thwait'
|
5
|
-
require 'yaml'
|
6
|
-
|
7
2
|
module RabbitJobs
|
8
3
|
class Scheduler
|
4
|
+
include MainLoop
|
9
5
|
|
10
|
-
|
6
|
+
attr_reader :schedule, :process_name
|
7
|
+
attr_writer :process_name
|
8
|
+
|
9
|
+
def schedule=(value)
|
10
|
+
@schedule = HashWithIndifferentAccess.new(value)
|
11
|
+
end
|
11
12
|
|
12
13
|
def load_default_schedule
|
13
14
|
if defined?(Rails)
|
14
15
|
file = Rails.root.join('config/schedule.yml')
|
15
16
|
if file.file?
|
16
|
-
@schedule = YAML.load_file(file)
|
17
|
+
@schedule = HashWithIndifferentAccess.new(YAML.load_file(file))
|
17
18
|
end
|
18
19
|
end
|
19
20
|
end
|
@@ -31,21 +32,7 @@ module RabbitJobs
|
|
31
32
|
# job should be scheduled regardless of what ENV['RAILS_ENV'] is set
|
32
33
|
# to.
|
33
34
|
if config['rails_env'].nil? || rails_env_matches?(config)
|
34
|
-
|
35
|
-
interval_types = %w{cron every}
|
36
|
-
interval_types.each do |interval_type|
|
37
|
-
if !config[interval_type].nil? && config[interval_type].length > 0
|
38
|
-
RJ.logger.info "queueing #{config['class']} (#{name})"
|
39
|
-
rufus_scheduler.send(interval_type, config[interval_type], blocking: true) do
|
40
|
-
publish_from_config(config)
|
41
|
-
end
|
42
|
-
interval_defined = true
|
43
|
-
break
|
44
|
-
end
|
45
|
-
end
|
46
|
-
unless interval_defined
|
47
|
-
RJ.logger.warn "no #{interval_types.join(' / ')} found for #{config['class']} (#{name}) - skipping"
|
48
|
-
end
|
35
|
+
setup_job_schedule(name, config)
|
49
36
|
end
|
50
37
|
end
|
51
38
|
end
|
@@ -57,16 +44,15 @@ module RabbitJobs
|
|
57
44
|
|
58
45
|
# Publish a job based on a config hash
|
59
46
|
def publish_from_config(config)
|
60
|
-
args = config[
|
61
|
-
klass_name = config[
|
62
|
-
params =
|
63
|
-
queue = config['queue'] || config[:queue] || RJ.config.routing_keys.first
|
47
|
+
args = config[:args] || []
|
48
|
+
klass_name = config[:class]
|
49
|
+
params = [args].flatten
|
64
50
|
|
65
|
-
|
66
|
-
|
51
|
+
RabbitJobs.logger.info "publishing #{config} at #{Time.now}"
|
52
|
+
RabbitJobs.publish_to(config[:queue], klass_name, *params)
|
67
53
|
rescue
|
68
|
-
|
69
|
-
|
54
|
+
RabbitJobs.logger.warn "Failed to publish #{klass_name}:\n #{$!}\n params = #{params.inspect}"
|
55
|
+
RabbitJobs.logger.warn $!.inspect
|
70
56
|
end
|
71
57
|
|
72
58
|
def rufus_scheduler
|
@@ -88,46 +74,18 @@ module RabbitJobs
|
|
88
74
|
|
89
75
|
$0 = self.process_name || "rj_scheduler"
|
90
76
|
|
91
|
-
|
77
|
+
RabbitJobs.logger.info "Started."
|
92
78
|
|
93
|
-
processed_count = 0
|
94
79
|
load_schedule!
|
95
80
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
time -= 1
|
100
|
-
if time == 0
|
101
|
-
shutdown
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
if @shutdown
|
106
|
-
RJ.logger.info "Processed jobs: #{processed_count}."
|
107
|
-
RJ.logger.info "Stopped."
|
108
|
-
|
109
|
-
return true
|
110
|
-
end
|
111
|
-
end
|
112
|
-
rescue => e
|
113
|
-
error = $!
|
114
|
-
if RJ.logger
|
115
|
-
begin
|
116
|
-
RJ.logger.error [error.message, error.backtrace].flatten.join("\n")
|
117
|
-
ensure
|
118
|
-
abort(error.message)
|
119
|
-
end
|
120
|
-
end
|
81
|
+
return main_loop(time)
|
82
|
+
rescue
|
83
|
+
log_daemon_error($!)
|
121
84
|
end
|
122
85
|
|
123
86
|
true
|
124
87
|
end
|
125
88
|
|
126
|
-
def shutdown
|
127
|
-
RJ.logger.info "Stopping..."
|
128
|
-
@shutdown = true
|
129
|
-
end
|
130
|
-
|
131
89
|
def startup
|
132
90
|
# Fix buffering so we can `rake rj:work > resque.log` and
|
133
91
|
# get output from the child in there.
|
@@ -141,8 +99,20 @@ module RabbitJobs
|
|
141
99
|
true
|
142
100
|
end
|
143
101
|
|
144
|
-
def
|
145
|
-
|
102
|
+
def setup_job_schedule(name, config)
|
103
|
+
interval_defined = false
|
104
|
+
%w(cron every).each do |interval_type|
|
105
|
+
if config[interval_type].present?
|
106
|
+
RabbitJobs.logger.info "queueing #{config['class']} (#{name})"
|
107
|
+
rufus_scheduler.send(interval_type, config[interval_type], blocking: true) do
|
108
|
+
publish_from_config(config)
|
109
|
+
end
|
110
|
+
interval_defined = true
|
111
|
+
end
|
112
|
+
end
|
113
|
+
unless interval_defined
|
114
|
+
RabbitJobs.logger.warn "no #{interval_types.join(' / ')} found for #{config['class']} (#{name}) - skipping"
|
115
|
+
end
|
146
116
|
end
|
147
117
|
end
|
148
118
|
end
|
data/lib/rabbit_jobs/tasks.rb
CHANGED
data/lib/rabbit_jobs/version.rb
CHANGED
data/lib/rabbit_jobs/worker.rb
CHANGED
@@ -2,12 +2,14 @@
|
|
2
2
|
|
3
3
|
module RabbitJobs
|
4
4
|
class Worker
|
5
|
+
include MainLoop
|
6
|
+
|
5
7
|
attr_accessor :process_name
|
6
8
|
attr_reader :consumer
|
7
9
|
|
8
|
-
def consumer=(
|
9
|
-
raise ArgumentError.new("
|
10
|
-
@consumer =
|
10
|
+
def consumer=(value)
|
11
|
+
raise ArgumentError.new("value=#{value.inspect}") unless value.respond_to?(:process_message)
|
12
|
+
@consumer = value
|
11
13
|
end
|
12
14
|
|
13
15
|
def amqp_connection
|
@@ -20,12 +22,8 @@ module RabbitJobs
|
|
20
22
|
Thread.current[:rj_worker_connection] = nil
|
21
23
|
end
|
22
24
|
|
23
|
-
def queue_name(routing_key)
|
24
|
-
RJ.config.queue_name(routing_key)
|
25
|
-
end
|
26
|
-
|
27
25
|
def queue_params(routing_key)
|
28
|
-
RJ.config[:queues][routing_key]
|
26
|
+
RJ.config[:queues][routing_key.to_sym]
|
29
27
|
end
|
30
28
|
|
31
29
|
# Workers should be initialized with an array of string queue
|
@@ -58,79 +56,28 @@ module RabbitJobs
|
|
58
56
|
|
59
57
|
$0 = self.process_name || "rj_worker (#{queues.join(', ')})"
|
60
58
|
|
61
|
-
processed_count = 0
|
59
|
+
@processed_count = 0
|
62
60
|
|
63
61
|
begin
|
64
|
-
# amqp_channel.prefetch(1)
|
65
|
-
|
66
62
|
amqp_channel = amqp_connection.create_channel
|
63
|
+
amqp_channel.prefetch(1)
|
67
64
|
|
68
|
-
queue_objects = []
|
69
65
|
queues.each do |routing_key|
|
70
|
-
|
71
|
-
|
72
|
-
routing_key = routing_key.to_sym
|
73
|
-
queue = amqp_channel.queue(queue_name(routing_key), queue_params(routing_key))
|
74
|
-
queue_objects << queue
|
75
|
-
explicit_ack = !!queue_params(routing_key)[:ack]
|
76
|
-
|
77
|
-
queue.subscribe(ack: explicit_ack) do |delivery_info, properties, payload|
|
78
|
-
if RJ.run_before_process_message_callbacks
|
79
|
-
begin
|
80
|
-
@consumer.process_message(delivery_info, properties, payload)
|
81
|
-
processed_count += 1
|
82
|
-
rescue
|
83
|
-
RJ.logger.warn "process_message failed. payload: #{payload.inspect}"
|
84
|
-
RJ.logger.warn $!.inspect
|
85
|
-
$!.backtrace.each {|l| RJ.logger.warn l}
|
86
|
-
end
|
87
|
-
amqp_channel.ack(delivery_info.delivery_tag, false) if explicit_ack
|
88
|
-
else
|
89
|
-
RJ.logger.warn "before_process_message hook failed, requeuing payload: #{payload.inspect}"
|
90
|
-
amqp_channel.nack(delivery_info.delivery_tag, true) if explicit_ack
|
91
|
-
end
|
92
|
-
|
93
|
-
if @shutdown
|
94
|
-
queue_objects.each {|q| q.unsubscribe}
|
95
|
-
end
|
96
|
-
end
|
66
|
+
consume_queue(amqp_channel, routing_key)
|
97
67
|
end
|
98
68
|
|
99
69
|
RJ.logger.info "Started."
|
100
70
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
time -= 1
|
105
|
-
if time == 0
|
106
|
-
shutdown
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
if @shutdown
|
111
|
-
RJ.logger.info "Processed jobs: #{processed_count}."
|
112
|
-
RJ.logger.info "Stopped."
|
113
|
-
return true
|
114
|
-
end
|
115
|
-
end
|
71
|
+
return main_loop(time) {
|
72
|
+
RJ.logger.info "Processed jobs: #{@processed_count}."
|
73
|
+
}
|
116
74
|
rescue
|
117
|
-
|
118
|
-
if RJ.logger
|
119
|
-
begin
|
120
|
-
RJ.logger.error [error.message, error.backtrace].flatten.join("\n")
|
121
|
-
ensure
|
122
|
-
abort(error.message)
|
123
|
-
end
|
124
|
-
end
|
75
|
+
log_daemon_error($!)
|
125
76
|
end
|
126
77
|
|
127
78
|
true
|
128
79
|
end
|
129
80
|
|
130
|
-
def shutdown
|
131
|
-
@shutdown = true
|
132
|
-
end
|
133
|
-
|
134
81
|
def startup
|
135
82
|
count = RJ._run_after_fork_callbacks
|
136
83
|
|
@@ -144,8 +91,38 @@ module RabbitJobs
|
|
144
91
|
true
|
145
92
|
end
|
146
93
|
|
147
|
-
|
148
|
-
|
94
|
+
private
|
95
|
+
|
96
|
+
def consume_message(delivery_info, properties, payload)
|
97
|
+
if RJ.run_before_process_message_callbacks
|
98
|
+
begin
|
99
|
+
@consumer.process_message(delivery_info, properties, payload)
|
100
|
+
@processed_count += 1
|
101
|
+
rescue
|
102
|
+
RJ.logger.warn "process_message failed. payload: #{payload.inspect}"
|
103
|
+
RJ.logger.warn $!.inspect
|
104
|
+
$!.backtrace.each {|l| RJ.logger.warn l}
|
105
|
+
end
|
106
|
+
true
|
107
|
+
else
|
108
|
+
RJ.logger.warn "before_process_message hook failed, requeuing payload: #{payload.inspect}"
|
109
|
+
false
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def consume_queue(amqp_channel, routing_key)
|
114
|
+
RJ.logger.info "Subscribing to #{routing_key}"
|
115
|
+
routing_key = routing_key.to_sym
|
116
|
+
queue = amqp_channel.queue(routing_key, queue_params(routing_key))
|
117
|
+
explicit_ack = !!queue_params(routing_key)[:ack]
|
118
|
+
|
119
|
+
queue.subscribe(ack: explicit_ack) do |delivery_info, properties, payload|
|
120
|
+
if consume_message(delivery_info, properties, payload)
|
121
|
+
amqp_channel.ack(delivery_info.delivery_tag, false) if explicit_ack
|
122
|
+
else
|
123
|
+
amqp_channel.nack(delivery_info.delivery_tag, true) if explicit_ack
|
124
|
+
end
|
125
|
+
end
|
149
126
|
end
|
150
127
|
end
|
151
128
|
end
|
data/lib/rabbit_jobs.rb
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
require 'logger'
|
3
3
|
require 'rake'
|
4
|
+
require 'json'
|
5
|
+
require 'digest/md5'
|
6
|
+
require 'bunny'
|
7
|
+
require 'uri'
|
8
|
+
require 'rufus/scheduler'
|
9
|
+
require 'thwait'
|
10
|
+
require 'yaml'
|
11
|
+
require 'active_support'
|
12
|
+
require 'active_support/core_ext'
|
4
13
|
|
5
14
|
require 'rabbit_jobs/version'
|
6
15
|
|
@@ -12,6 +21,7 @@ require 'rabbit_jobs/error_mailer'
|
|
12
21
|
require 'rabbit_jobs/consumer/job_consumer'
|
13
22
|
require 'rabbit_jobs/job'
|
14
23
|
require 'rabbit_jobs/publisher'
|
24
|
+
require 'rabbit_jobs/main_loop'
|
15
25
|
require 'rabbit_jobs/worker'
|
16
26
|
require 'rabbit_jobs/scheduler'
|
17
27
|
require 'rabbit_jobs/tasks'
|
@@ -20,15 +30,15 @@ module RabbitJobs
|
|
20
30
|
extend self
|
21
31
|
|
22
32
|
def publish_to(routing_key, klass, *params)
|
23
|
-
|
33
|
+
Publisher.publish_to(routing_key, klass, *params)
|
24
34
|
end
|
25
35
|
|
26
36
|
def direct_publish_to(routing_key, payload, ex = {})
|
27
|
-
|
37
|
+
Publisher.direct_publish_to(routing_key, payload, ex)
|
28
38
|
end
|
29
39
|
|
30
40
|
def purge_queue(*routing_keys)
|
31
|
-
|
41
|
+
Publisher.purge_queue(*routing_keys)
|
32
42
|
end
|
33
43
|
|
34
44
|
attr_writer :logger
|
data/spec/fixtures/config.yml
CHANGED
data/spec/fixtures/jobs.rb
CHANGED
@@ -34,7 +34,7 @@ class JobWithPublish
|
|
34
34
|
def self.perform(param = 0)
|
35
35
|
if param < 5
|
36
36
|
puts "publishing job #{param}"
|
37
|
-
RJ.
|
37
|
+
RJ.publish_to :rspec_durable_queue, JobWithPublish, param + 1
|
38
38
|
else
|
39
39
|
puts "processing job #{param}"
|
40
40
|
end
|
@@ -64,4 +64,9 @@ class JobWithArgsArray
|
|
64
64
|
def perform(first_param, *other_args)
|
65
65
|
puts "#{self.class.name}.perform called with first_param: #{first_param.inspect} and other_args: #{other_args.inspect}"
|
66
66
|
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class TestConsumer
|
70
|
+
def process_message *args
|
71
|
+
end
|
67
72
|
end
|
@@ -43,7 +43,7 @@ describe RabbitJobs::Publisher do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
it 'should publish 1000 messages in one second' do
|
46
|
-
count =
|
46
|
+
count = 1000
|
47
47
|
published = 0
|
48
48
|
time = Benchmark.measure {
|
49
49
|
count.times {
|
@@ -51,7 +51,7 @@ describe RabbitJobs::Publisher do
|
|
51
51
|
}
|
52
52
|
# sleep 0.1
|
53
53
|
removed = RJ.purge_queue(:rspec_queue, :rspec_queue2, :rspec_queue3)
|
54
|
-
removed.should ==
|
54
|
+
removed.should == 1000
|
55
55
|
}
|
56
56
|
puts time
|
57
57
|
end
|
@@ -4,39 +4,43 @@ require 'spec_helper'
|
|
4
4
|
describe RabbitJobs::Worker do
|
5
5
|
it 'should listen for messages' do
|
6
6
|
RabbitJobs.configure do |c|
|
7
|
-
c.
|
7
|
+
c.server 'amqp://localhost/rj'
|
8
8
|
c.queue 'rspec_durable_queue', auto_delete: false, durable: true, ack: true
|
9
9
|
end
|
10
10
|
|
11
11
|
RJ::Publisher.purge_queue('rspec_durable_queue')
|
12
12
|
count = 5
|
13
13
|
5.times {
|
14
|
-
RabbitJobs.
|
14
|
+
RabbitJobs.publish_to(:rspec_durable_queue, PrintTimeJob, Time.now)
|
15
15
|
}
|
16
16
|
|
17
17
|
Timecop.freeze(Time.now - 4600) {
|
18
|
-
5.times { RabbitJobs.
|
18
|
+
5.times { RabbitJobs.publish_to(:rspec_durable_queue, JobWithExpire) }
|
19
19
|
}
|
20
20
|
|
21
|
-
RabbitJobs.
|
21
|
+
RabbitJobs.publish_to(:rspec_durable_queue, JobWithErrorHook)
|
22
22
|
|
23
23
|
worker = RabbitJobs::Worker.new
|
24
|
+
RJ.logger.level = Logger::FATAL
|
24
25
|
|
26
|
+
mock(PrintTimeJob).perform(anything).times(5)
|
27
|
+
mock(JobWithErrorHook).perform
|
28
|
+
dont_allow(JobWithExpire).perform
|
25
29
|
worker.work(1) # work for 1 second
|
26
30
|
RJ::Publisher.purge_queue('rspec_durable_queue')
|
27
31
|
end
|
28
32
|
|
29
33
|
it 'should allow to publish jobs from worker' do
|
30
34
|
RabbitJobs.configure do |c|
|
31
|
-
c.
|
35
|
+
c.server 'amqp://localhost/rj'
|
32
36
|
c.queue 'rspec_durable_queue', auto_delete: false, durable: true, ack: true
|
33
37
|
end
|
34
38
|
|
35
39
|
RJ::Publisher.purge_queue('rspec_durable_queue')
|
36
|
-
RabbitJobs.
|
40
|
+
RabbitJobs.publish_to(:rspec_durable_queue, JobWithPublish, 1)
|
37
41
|
|
38
42
|
worker = RabbitJobs::Worker.new
|
39
|
-
|
40
|
-
worker.work(
|
43
|
+
# mock(RJ).publish_to(:rspec_durable_queue, JobWithPublish, 5)
|
44
|
+
worker.work(3) # work for 1 second
|
41
45
|
end
|
42
46
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -20,4 +20,12 @@ RSpec.configure do |config|
|
|
20
20
|
# clear config options
|
21
21
|
RabbitJobs.class_variable_set '@@configuration', nil
|
22
22
|
end
|
23
|
+
|
24
|
+
if ENV['CC_BUILD_ARTIFACTS']
|
25
|
+
# "-c -f p -f h -o #{ENV['CC_BUILD_ARTIFACTS']}/rspec_report.html"
|
26
|
+
config.out = File.open "#{ENV['CC_BUILD_ARTIFACTS']}/rspec_report.html", 'w'
|
27
|
+
# config.color_enabled = true
|
28
|
+
# config.formatter = :progress
|
29
|
+
config.formatter = :html
|
30
|
+
end
|
23
31
|
end
|
@@ -8,8 +8,6 @@ describe RabbitJobs::Configuration do
|
|
8
8
|
|
9
9
|
c.server "amqp://somehost.lan"
|
10
10
|
|
11
|
-
c.prefix 'my_prefix'
|
12
|
-
|
13
11
|
c.queue 'durable_queue', durable: true, auto_delete: false, ack: true, arguments: {'x-ha-policy' => 'all'}
|
14
12
|
c.queue 'fast_queue', durable: false, auto_delete: true, ack: false
|
15
13
|
end
|
@@ -17,7 +15,6 @@ describe RabbitJobs::Configuration do
|
|
17
15
|
RabbitJobs.config.to_hash.should == {
|
18
16
|
error_log: false,
|
19
17
|
server: "amqp://somehost.lan",
|
20
|
-
prefix: "my_prefix",
|
21
18
|
queues: {
|
22
19
|
durable_queue: {
|
23
20
|
auto_delete: false,
|
@@ -40,7 +37,6 @@ describe RabbitJobs::Configuration do
|
|
40
37
|
RabbitJobs.config.load_file(File.expand_path('../../fixtures/config.yml', __FILE__))
|
41
38
|
|
42
39
|
RabbitJobs.config.to_hash.should == {
|
43
|
-
prefix: "rabbit_jobs",
|
44
40
|
server: "amqp://example.com/vhost",
|
45
41
|
queues: {
|
46
42
|
durable_queue: {
|
@@ -60,19 +56,17 @@ describe RabbitJobs::Configuration do
|
|
60
56
|
}
|
61
57
|
end
|
62
58
|
|
63
|
-
it 'use default
|
59
|
+
it 'use default value for #server' do
|
64
60
|
RabbitJobs.config.to_hash.should == {
|
65
61
|
error_log: true,
|
66
|
-
server: "amqp://localhost
|
67
|
-
prefix: "rabbit_jobs",
|
62
|
+
server: "amqp://localhost",
|
68
63
|
queues: {}
|
69
64
|
}
|
70
65
|
end
|
71
66
|
|
72
67
|
it 'returns settings on some methods' do
|
73
68
|
RabbitJobs.config.error_log == true
|
74
|
-
RabbitJobs.config.server.should == 'amqp://localhost
|
69
|
+
RabbitJobs.config.server.should == 'amqp://localhost'
|
75
70
|
RabbitJobs.config.routing_keys.should == []
|
76
|
-
RabbitJobs.config.prefix.should == 'rabbit_jobs'
|
77
71
|
end
|
78
72
|
end
|
data/spec/unit/worker_spec.rb
CHANGED
@@ -2,30 +2,25 @@
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe RabbitJobs::Worker do
|
5
|
-
describe 'methods' do
|
6
|
-
before :each do
|
7
|
-
@worker = RabbitJobs::Worker.new
|
8
|
-
end
|
9
5
|
|
10
|
-
|
11
|
-
|
6
|
+
before(:each) do
|
7
|
+
RJ.configure do |c|
|
8
|
+
c.server 'amqp://localhost'
|
9
|
+
c.queue "default"
|
12
10
|
end
|
11
|
+
end
|
13
12
|
|
14
|
-
|
15
|
-
@worker.instance_variable_get('@shutdown').should_not == true
|
16
|
-
|
17
|
-
mock(Signal).trap('TERM')
|
18
|
-
mock(Signal).trap('INT')
|
19
|
-
|
20
|
-
@worker.startup
|
13
|
+
let(:worker) { RJ::Worker.new(:default) }
|
21
14
|
|
22
|
-
|
23
|
-
|
15
|
+
describe '#consumer' do
|
16
|
+
it 'validates consumer type' do
|
17
|
+
old_consumer = worker.consumer
|
18
|
+
lambda { worker.consumer = 123 }.should raise_error
|
19
|
+
worker.consumer.should == old_consumer
|
24
20
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
@worker.instance_variable_get('@shutdown').should == true
|
21
|
+
new_consumer = TestConsumer.new
|
22
|
+
lambda { worker.consumer = new_consumer }.should_not raise_error
|
23
|
+
worker.consumer.should == new_consumer
|
29
24
|
end
|
30
25
|
end
|
31
26
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rabbit_jobs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bunny
|
16
|
-
requirement: &
|
16
|
+
requirement: &17412060 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - =
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.9.0.pre8
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *17412060
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &17409580 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *17409580
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rufus-scheduler
|
38
|
-
requirement: &
|
38
|
+
requirement: &17800900 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '2.0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *17800900
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rails
|
49
|
-
requirement: &
|
49
|
+
requirement: &17799580 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: '3.0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *17799580
|
58
58
|
description: Background jobs on RabbitMQ
|
59
59
|
email:
|
60
60
|
- lazureykis@gmail.com
|
@@ -81,6 +81,7 @@ files:
|
|
81
81
|
- lib/rabbit_jobs/error_mailer.rb
|
82
82
|
- lib/rabbit_jobs/helpers.rb
|
83
83
|
- lib/rabbit_jobs/job.rb
|
84
|
+
- lib/rabbit_jobs/main_loop.rb
|
84
85
|
- lib/rabbit_jobs/publisher.rb
|
85
86
|
- lib/rabbit_jobs/scheduler.rb
|
86
87
|
- lib/rabbit_jobs/tasks.rb
|
@@ -114,7 +115,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
114
115
|
version: '0'
|
115
116
|
segments:
|
116
117
|
- 0
|
117
|
-
hash: -
|
118
|
+
hash: -1527066833663791632
|
118
119
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
120
|
none: false
|
120
121
|
requirements:
|
@@ -123,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
124
|
version: '0'
|
124
125
|
segments:
|
125
126
|
- 0
|
126
|
-
hash: -
|
127
|
+
hash: -1527066833663791632
|
127
128
|
requirements: []
|
128
129
|
rubyforge_project:
|
129
130
|
rubygems_version: 1.8.11
|