rabbit_jobs 0.4.11 → 0.4.12
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/examples/client +13 -15
- data/lib/rabbit_jobs/amqp_helper.rb +26 -17
- data/lib/rabbit_jobs/configuration.rb +12 -7
- data/lib/rabbit_jobs/publisher.rb +17 -14
- data/lib/rabbit_jobs/tasks.rb +8 -7
- data/lib/rabbit_jobs/version.rb +1 -1
- data/lib/rabbit_jobs/worker.rb +5 -3
- data/lib/rabbit_jobs.rb +4 -2
- data/spec/unit/worker_spec.rb +1 -1
- metadata +12 -12
data/examples/client
CHANGED
@@ -13,9 +13,7 @@ end
|
|
13
13
|
|
14
14
|
RJ.configure { |c|
|
15
15
|
c.queue "failover_test"
|
16
|
-
c.server "amqp://dev.lan/"
|
17
16
|
c.server "amqp://localhost/"
|
18
|
-
|
19
17
|
}
|
20
18
|
|
21
19
|
RJ.logger = Logger.new($stdout)
|
@@ -35,16 +33,16 @@ RJ.run {
|
|
35
33
|
}
|
36
34
|
|
37
35
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
36
|
+
1000.times {
|
37
|
+
RJ.run do
|
38
|
+
count = 10000
|
39
|
+
published = 0
|
40
|
+
count.times {
|
41
|
+
RJ.publish_to(:default, MyCurrentJob) {
|
42
|
+
published += 1
|
43
|
+
RJ.stop if published >= count
|
44
|
+
}
|
45
|
+
}
|
46
|
+
end
|
47
|
+
puts 'returned from em'
|
48
|
+
}
|
@@ -9,19 +9,20 @@ module RabbitJobs
|
|
9
9
|
RECOVERY_TIMEOUT = 3
|
10
10
|
HOSTS_DEAD = []
|
11
11
|
HOSTS_FAILED = {}
|
12
|
+
AUTO_RECOVERY_ENABLED = true
|
12
13
|
|
13
14
|
class << self
|
14
15
|
|
15
16
|
def prepare_connection
|
16
17
|
if !AMQP.connection || AMQP.connection.closed?
|
17
18
|
RJ.logger.info("Connecting to #{RJ.config.servers.first.to_s}...")
|
18
|
-
AMQP.connection = AMQP.connect(RJ.config.servers.first, auto_recovery:
|
19
|
-
init_auto_recovery
|
19
|
+
AMQP.connection = AMQP.connect(RJ.config.servers.first, auto_recovery: AUTO_RECOVERY_ENABLED)
|
20
|
+
init_auto_recovery if AUTO_RECOVERY_ENABLED
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
23
24
|
def prepare_channel
|
24
|
-
AMQP.channel ||= AMQP::Channel.new(AMQP.connection, auto_recovery:
|
25
|
+
AMQP.channel ||= AMQP::Channel.new(AMQP.connection, auto_recovery: AUTO_RECOVERY_ENABLED)
|
25
26
|
end
|
26
27
|
|
27
28
|
def init_auto_recovery
|
@@ -39,6 +40,17 @@ module RabbitJobs
|
|
39
40
|
RJ.logger.info "Connected."
|
40
41
|
end
|
41
42
|
|
43
|
+
AMQP.connection.on_tcp_connection_loss do |conn, opts|
|
44
|
+
sleep 2
|
45
|
+
restore_from_connection_failure(opts)
|
46
|
+
end
|
47
|
+
|
48
|
+
AMQP.connection.on_tcp_connection_failure do |opts|
|
49
|
+
sleep 2
|
50
|
+
restore_from_connection_failure(opts)
|
51
|
+
end
|
52
|
+
|
53
|
+
|
42
54
|
# AMQP.connection.before_recovery do |conn, opts|
|
43
55
|
# RJ.logger.info "before_recovery"
|
44
56
|
# end
|
@@ -48,19 +60,9 @@ module RabbitJobs
|
|
48
60
|
# # restore_from_connection_failure(opts)
|
49
61
|
# end
|
50
62
|
|
51
|
-
AMQP.connection.on_tcp_connection_loss do |conn, opts|
|
52
|
-
sleep 2
|
53
|
-
restore_from_connection_failure(opts)
|
54
|
-
end
|
55
|
-
|
56
63
|
# AMQP.connection.on_connection_interruption do |conn|
|
57
64
|
# # restore_from_connection_failure(opts)
|
58
65
|
# end
|
59
|
-
|
60
|
-
AMQP.connection.on_tcp_connection_failure do |opts|
|
61
|
-
sleep 2
|
62
|
-
restore_from_connection_failure(opts)
|
63
|
-
end
|
64
66
|
end
|
65
67
|
end
|
66
68
|
|
@@ -99,13 +101,20 @@ module RabbitJobs
|
|
99
101
|
def url_from_opts(opts = {})
|
100
102
|
return "" unless opts
|
101
103
|
return "" if opts.empty?
|
104
|
+
|
105
|
+
scheme = opts[:scheme] || "amqp"
|
106
|
+
vhost = opts[:vhost] || "/"
|
107
|
+
vhost = "/#{vhost}" unless vhost[0] == '/'
|
108
|
+
use_default_port = (scheme == 'amqp' && opts[:port] == 5672) || (scheme == 'amqps' && opts[:port] == 5673)
|
109
|
+
use_default_credentials = opts[:user] == 'guest' && opts[:pass] == 'guest'
|
110
|
+
|
102
111
|
s = ""
|
103
|
-
s <<
|
112
|
+
s << scheme
|
104
113
|
s << "://"
|
105
|
-
s << "#{opts[:user]}
|
114
|
+
s << "#{opts[:user]}:#{opts[:pass]}@" unless use_default_credentials
|
106
115
|
s << opts[:host]
|
107
|
-
s << ":#{opts[:port]}" unless
|
108
|
-
s <<
|
116
|
+
s << ":#{opts[:port]}" unless use_default_port
|
117
|
+
s << vhost
|
109
118
|
s
|
110
119
|
end
|
111
120
|
end
|
@@ -63,10 +63,10 @@ module RabbitJobs
|
|
63
63
|
def initialize
|
64
64
|
@data = {
|
65
65
|
error_log: true,
|
66
|
-
workers:
|
66
|
+
workers: {},
|
67
67
|
servers: [],
|
68
68
|
prefix: 'rabbit_jobs',
|
69
|
-
queues:
|
69
|
+
queues: {}
|
70
70
|
}
|
71
71
|
end
|
72
72
|
|
@@ -127,7 +127,7 @@ module RabbitJobs
|
|
127
127
|
raise ArgumentError.new("name is #{name.inspect}") unless name && name.is_a?(String) && name != ""
|
128
128
|
raise ArgumentError.new("params is #{params.inspect}") unless params && params.is_a?(Hash)
|
129
129
|
|
130
|
-
name = name.downcase
|
130
|
+
name = name.downcase.to_sym
|
131
131
|
|
132
132
|
if @data[:queues][name]
|
133
133
|
@data[:queues][name].merge!(params)
|
@@ -137,7 +137,7 @@ module RabbitJobs
|
|
137
137
|
end
|
138
138
|
|
139
139
|
def workers
|
140
|
-
@data[:workers] ||=
|
140
|
+
@data[:workers] ||= {}
|
141
141
|
end
|
142
142
|
|
143
143
|
def worker(name, params = {})
|
@@ -145,9 +145,9 @@ module RabbitJobs
|
|
145
145
|
raise ArgumentError.new("params is #{params.inspect}") unless params && params.is_a?(Hash)
|
146
146
|
raise ArgumentError.new("params should have :instances and :queues keys.") unless params[:instances] && params[:queues]
|
147
147
|
|
148
|
-
name = name.downcase
|
148
|
+
name = name.downcase.to_sym
|
149
149
|
|
150
|
-
@data[:workers] ||=
|
150
|
+
@data[:workers] ||= {}
|
151
151
|
if @data[:workers][name]
|
152
152
|
@data[:workers][name].merge!(params)
|
153
153
|
else
|
@@ -163,12 +163,17 @@ module RabbitJobs
|
|
163
163
|
queue('default', DEFAULT_QUEUE_PARAMS) if @data[:queues].empty?
|
164
164
|
end
|
165
165
|
|
166
|
+
def worker_queues
|
167
|
+
@data[:workers].values.map{|w| w[:queues].to_s.split(' ')}.flatten.uniq.sort
|
168
|
+
end
|
169
|
+
|
166
170
|
def default_queue
|
167
171
|
queue('default', DEFAULT_QUEUE_PARAMS) if @data[:queues].empty?
|
168
|
-
|
172
|
+
worker_queues.first
|
169
173
|
end
|
170
174
|
|
171
175
|
def queue_name(routing_key)
|
176
|
+
routing_key = routing_key.to_sym
|
172
177
|
@data[:queues][routing_key][:ignore_prefix] ? routing_key : [@data[:prefix], routing_key].join('#')
|
173
178
|
end
|
174
179
|
|
@@ -15,7 +15,7 @@ module RabbitJobs
|
|
15
15
|
|
16
16
|
def publish_to(routing_key, klass, *params, &block)
|
17
17
|
raise ArgumentError.new("klass=#{klass.inspect}") unless klass && (klass.is_a?(Class) || klass.is_a?(String))
|
18
|
-
raise ArgumentError.new("routing_key=#{routing_key}") unless routing_key && (routing_key.is_a?(Symbol) || routing_key.is_a?(String)) && !!RJ.config[:queues][routing_key.
|
18
|
+
raise ArgumentError.new("routing_key=#{routing_key}") unless routing_key && (routing_key.is_a?(Symbol) || routing_key.is_a?(String)) && !!RJ.config[:queues][routing_key.to_sym]
|
19
19
|
|
20
20
|
payload = {
|
21
21
|
'class' => klass.to_s,
|
@@ -23,7 +23,7 @@ module RabbitJobs
|
|
23
23
|
'params' => params
|
24
24
|
}.to_json
|
25
25
|
|
26
|
-
direct_publish_to(RJ.config.queue_name(routing_key.
|
26
|
+
direct_publish_to(RJ.config.queue_name(routing_key.to_sym), payload, &block)
|
27
27
|
end
|
28
28
|
|
29
29
|
def direct_publish_to(routing_key, payload, ex = {}, &block)
|
@@ -35,12 +35,12 @@ module RabbitJobs
|
|
35
35
|
|
36
36
|
if ex.size > 0
|
37
37
|
AMQP::Exchange.new(AMQP.channel, :direct, ex[:name].to_s, Configuration::DEFAULT_EXCHANGE_PARAMS.merge(ex[:params] || {})) do |exchange|
|
38
|
-
exchange.publish(payload, Configuration::DEFAULT_MESSAGE_PARAMS.merge({key: routing_key.
|
38
|
+
exchange.publish(payload, Configuration::DEFAULT_MESSAGE_PARAMS.merge({key: routing_key.to_sym})) do
|
39
39
|
yield if block_given?
|
40
40
|
end
|
41
41
|
end
|
42
42
|
else
|
43
|
-
AMQP.channel.default_exchange.publish(payload, Configuration::DEFAULT_MESSAGE_PARAMS.merge({key: routing_key.
|
43
|
+
AMQP.channel.default_exchange.publish(payload, Configuration::DEFAULT_MESSAGE_PARAMS.merge({key: routing_key.to_sym})) do
|
44
44
|
yield if block_given?
|
45
45
|
end
|
46
46
|
end
|
@@ -61,20 +61,23 @@ module RabbitJobs
|
|
61
61
|
|
62
62
|
AmqpHelper.prepare_channel
|
63
63
|
|
64
|
-
routing_keys.each do |routing_key|
|
65
|
-
|
66
|
-
queue.
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
64
|
+
routing_keys.map(&:to_s).each do |routing_key|
|
65
|
+
queue_name = RJ.config.queue_name(routing_key)
|
66
|
+
AMQP.channel.queue(queue_name, RJ.config[:queues][routing_key]) do |queue, declare_ok|
|
67
|
+
queue.status do |messages, consumers|
|
68
|
+
queue.purge do |ret|
|
69
|
+
RJ.logger.error "Cannot purge queue #{queue_name}." unless ret.is_a?(AMQ::Protocol::Queue::PurgeOk)
|
70
|
+
messages_count += ret.message_count
|
71
|
+
count -= 1
|
72
|
+
if count == 0
|
73
|
+
yield(messages_count) if block_given?
|
74
|
+
end
|
74
75
|
end
|
75
76
|
end
|
76
77
|
end
|
77
78
|
end
|
79
|
+
|
80
|
+
messages_count
|
78
81
|
end
|
79
82
|
end
|
80
83
|
end
|
data/lib/rabbit_jobs/tasks.rb
CHANGED
@@ -32,13 +32,15 @@ namespace :rj do
|
|
32
32
|
task :start => [:environment, :load_config] do
|
33
33
|
make_dirs
|
34
34
|
RJ.config.workers.each do |worker_name, worker_props|
|
35
|
-
|
36
|
-
worker_props[
|
35
|
+
puts worker_props.inspect
|
36
|
+
(1..worker_props[:instances].to_i).each do |worker_num|
|
37
37
|
unless @do_only.count > 0 && !@do_only.include?("#{worker_name}-#{worker_num}")
|
38
|
-
|
38
|
+
$stdout.puts 'initializing worker'
|
39
|
+
queues = (worker_props[:queue] || worker_props[:queues] || "").split(' ')
|
39
40
|
|
40
41
|
worker = RJ::Worker.new(*queues)
|
41
42
|
worker.background = true
|
43
|
+
worker.background = false
|
42
44
|
worker.process_name = "rj_worker #{worker_name}##{worker_num} #{rails_env} [#{queues.join(',')}]"
|
43
45
|
worker.pidfile = app_root.join("tmp/pids/rj_worker_#{rails_env}_#{worker_name}_#{worker_num}.pid")
|
44
46
|
RJ.logger = ::Logger.new(app_root.join("log/rj_worker_#{rails_env}_#{worker_name}_#{worker_num}.log"), 'daily')
|
@@ -50,7 +52,6 @@ namespace :rj do
|
|
50
52
|
# завершаем копию процесса, если воркер уже отработал
|
51
53
|
exit! if worker.work
|
52
54
|
end
|
53
|
-
worker_num += 1
|
54
55
|
end
|
55
56
|
end
|
56
57
|
end
|
@@ -62,7 +63,7 @@ namespace :rj do
|
|
62
63
|
|
63
64
|
RJ.config.workers.each do |worker_name, worker_props|
|
64
65
|
worker_num = 1
|
65
|
-
worker_props[
|
66
|
+
worker_props[:instances].to_i.times do
|
66
67
|
unless (@do_only.count > 0) && !@do_only.include?("#{worker_name}-#{worker_num}")
|
67
68
|
pidfile = app_root.join("tmp/pids/rj_worker_#{rails_env}_#{worker_name}_#{worker_num}.pid")
|
68
69
|
|
@@ -73,7 +74,7 @@ namespace :rj do
|
|
73
74
|
else
|
74
75
|
pid = open(pidfile).read.to_i
|
75
76
|
pids[pid] = pidfile
|
76
|
-
queues = (worker_props[
|
77
|
+
queues = (worker_props[:queue] || worker_props[:queues] || "").split(' ')
|
77
78
|
puts "Stopping rj_worker #{worker_name}##{worker_num} #{rails_env} [#{queues.join(',')}]"
|
78
79
|
end
|
79
80
|
end
|
@@ -119,7 +120,7 @@ namespace :rj do
|
|
119
120
|
|
120
121
|
RJ.config.workers.each do |worker_name, worker_props|
|
121
122
|
worker_num = 1
|
122
|
-
worker_props[
|
123
|
+
worker_props[:instances].to_i.times do
|
123
124
|
pidfile = app_root.join("tmp/pids/rj_worker_#{rails_env}_#{worker_name}_#{worker_num}.pid")
|
124
125
|
|
125
126
|
unless File.exists?(pidfile)
|
data/lib/rabbit_jobs/version.rb
CHANGED
data/lib/rabbit_jobs/worker.rb
CHANGED
@@ -53,14 +53,14 @@ module RabbitJobs
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def queues
|
56
|
-
@queues || [
|
56
|
+
@queues || [:default]
|
57
57
|
end
|
58
58
|
|
59
59
|
# Subscribes to queue and working on jobs
|
60
60
|
def work(time = 0)
|
61
61
|
return false unless startup
|
62
62
|
|
63
|
-
$0 = self.process_name || "rj_worker (#{queues.join(',')})"
|
63
|
+
$0 = self.process_name || "rj_worker (#{queues.join(', ')})"
|
64
64
|
|
65
65
|
processed_count = 0
|
66
66
|
|
@@ -79,9 +79,11 @@ module RabbitJobs
|
|
79
79
|
}
|
80
80
|
|
81
81
|
AmqpHelper.prepare_channel
|
82
|
+
AMQP.channel.prefetch(1)
|
82
83
|
|
83
84
|
queues.each do |routing_key|
|
84
|
-
|
85
|
+
routing_key = routing_key.to_sym
|
86
|
+
|
85
87
|
AMQP.channel.queue(queue_name(routing_key), queue_params(routing_key)) { |queue, declare_ok|
|
86
88
|
explicit_ack = !!queue_params(routing_key)[:ack]
|
87
89
|
|
data/lib/rabbit_jobs.rb
CHANGED
@@ -97,14 +97,16 @@ module RabbitJobs
|
|
97
97
|
if RJ.running?
|
98
98
|
RJ::Publisher.purge_queue(*routing_keys, &block)
|
99
99
|
else
|
100
|
+
messages_count = 0
|
100
101
|
RJ.run {
|
101
102
|
RJ::Publisher.purge_queue(*routing_keys) { |count|
|
103
|
+
messages_count = count
|
102
104
|
RJ.stop {
|
103
|
-
yield if block_given?
|
104
|
-
return count
|
105
|
+
yield(count) if block_given?
|
105
106
|
}
|
106
107
|
}
|
107
108
|
}
|
109
|
+
messages_count
|
108
110
|
end
|
109
111
|
end
|
110
112
|
|
data/spec/unit/worker_spec.rb
CHANGED
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.4.
|
4
|
+
version: 0.4.12
|
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-02-
|
12
|
+
date: 2013-02-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: amqp
|
16
|
-
requirement: &
|
16
|
+
requirement: &14934660 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0.9'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *14934660
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &14933760 !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: *14933760
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rufus-scheduler
|
38
|
-
requirement: &
|
38
|
+
requirement: &14932340 !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: *14932340
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rails
|
49
|
-
requirement: &
|
49
|
+
requirement: &14931420 !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: *14931420
|
58
58
|
description: Background jobs on RabbitMQ
|
59
59
|
email:
|
60
60
|
- lazureykis@gmail.com
|
@@ -115,7 +115,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
115
115
|
version: '0'
|
116
116
|
segments:
|
117
117
|
- 0
|
118
|
-
hash:
|
118
|
+
hash: 3434241684722293516
|
119
119
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
120
|
none: false
|
121
121
|
requirements:
|
@@ -124,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
124
124
|
version: '0'
|
125
125
|
segments:
|
126
126
|
- 0
|
127
|
-
hash:
|
127
|
+
hash: 3434241684722293516
|
128
128
|
requirements: []
|
129
129
|
rubyforge_project:
|
130
130
|
rubygems_version: 1.8.11
|