rabbit_jobs 0.4.11 → 0.4.12

Sign up to get free protection for your applications and to get access to all the features.
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
- # 1000.times {
39
- # RJ.run do
40
- # count = 10000
41
- # published = 0
42
- # count.times {
43
- # RJ.publish_to(:default, MyCurrentJob) {
44
- # published += 1
45
- # RJ.stop if published >= count
46
- # }
47
- # }
48
- # end
49
- # puts 'returned from em'
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: true)
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: true)
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 << (opts[:scheme] || "amqp")
112
+ s << scheme
104
113
  s << "://"
105
- s << "#{opts[:user]}@" if opts[:user] && !opts[:user].empty? && opts[:user] != 'guest'
114
+ s << "#{opts[:user]}:#{opts[:pass]}@" unless use_default_credentials
106
115
  s << opts[:host]
107
- s << ":#{opts[:port]}" unless (opts[:scheme] == 'amqp' && opts[:port] == 5672) || (opts[:scheme] == 'amqps' && opts[:port] == 5673)
108
- s << opts[:vhost] if opts[:vhost] && !opts[:vhost].empty? && opts[:vhost] != "/"
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: HashWithIndifferentAccess.new,
66
+ workers: {},
67
67
  servers: [],
68
68
  prefix: 'rabbit_jobs',
69
- queues: HashWithIndifferentAccess.new
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] ||= HashWithIndifferentAccess.new
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] ||= HashWithIndifferentAccess.new
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
- key = @data[:queues].keys.first
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.to_s]
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.to_s), payload, &block)
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.to_s})) do
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.to_s})) do
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
- queue = AMQP.channel.queue(RJ.config.queue_name(routing_key), RJ.config[:queues][routing_key.to_s])
66
- queue.status do |messages, consumers|
67
- # messages_count += messages
68
- queue.purge do |ret|
69
- raise "Cannot purge queue #{routing_key.to_s}." 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?
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
@@ -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
- worker_num = 1
36
- worker_props['instances'].to_i.times do
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
- queues = (worker_props['queue'] || worker_props['queues'] || "").split(' ')
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['instances'].to_i.times do
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['queue'] || worker_props['queues'] || "").split(' ')
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['instances'].to_i.times do
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)
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
3
  module RabbitJobs
4
- VERSION = "0.4.11"
4
+ VERSION = "0.4.12"
5
5
  end
@@ -53,14 +53,14 @@ module RabbitJobs
53
53
  end
54
54
 
55
55
  def queues
56
- @queues || ['default']
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
- AMQP.channel.prefetch(1)
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
 
@@ -8,7 +8,7 @@ describe RabbitJobs::Worker do
8
8
  end
9
9
 
10
10
  it '#initialize with default options' do
11
- @worker.queues.should == ['default']
11
+ @worker.queues.should == [:default]
12
12
  end
13
13
 
14
14
  it '#startup should set @shutdown to false' do
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.11
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 00:00:00.000000000 Z
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: &19887240 !ruby/object:Gem::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: *19887240
24
+ version_requirements: *14934660
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &19886380 !ruby/object:Gem::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: *19886380
35
+ version_requirements: *14933760
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rufus-scheduler
38
- requirement: &19885520 !ruby/object:Gem::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: *19885520
46
+ version_requirements: *14932340
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rails
49
- requirement: &19884380 !ruby/object:Gem::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: *19884380
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: -3095640351894679385
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: -3095640351894679385
127
+ hash: 3434241684722293516
128
128
  requirements: []
129
129
  rubyforge_project:
130
130
  rubygems_version: 1.8.11