beetle 0.2.9.7 → 0.2.9.8

Sign up to get free protection for your applications and to get access to all the features.
data/RELEASE_NOTES.rdoc CHANGED
@@ -1,10 +1,24 @@
1
1
  = Release Notes
2
2
 
3
+ == Version 0.2.9.8
4
+
5
+ * since version 2.0, RabbitMQ supports Basic.reject(:requeue => true). we use it now too,
6
+ because it enhances performance of message processors. this means of course, you can
7
+ only use beetle gem versions >= 0.2.9.8 if your rabbitmq brokers are at least version 2.0.
8
+ * publishing timeout defaults to 0 to avoid extreme message loss in some cases
9
+
10
+
11
+ == Version 0.2.9.7
12
+
13
+ * use new bunny_ext gem and allow specification of global publishing timeouts
14
+ * registering a message now automatically registers the corresponding exchange
15
+ * don't try to bind queues for an exchange hich has no queue
16
+ * ruby 1.9.2 compatibility fixes
17
+
3
18
  == Version 0.2.9
4
19
 
5
20
  * Beetle::Client now raises an exception when it fails to publish a message to at least 1 RabbitMQ server
6
21
  * Subscribers are now stopped cleanly to avoid 'closed abruptly' messages in the RabbitMQ server log
7
- * Added send and receive timeouts on the socket and use system_timer for ruby side timeouts
8
22
 
9
23
  == Version 0.2.6
10
24
 
data/beetle.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "beetle"
3
- s.version = "0.2.9.7"
3
+ s.version = "0.2.9.8"
4
4
 
5
5
  s.required_rubygems_version = ">= 1.3.1"
6
6
  s.authors = ["Stefan Kaes", "Pascal Friederich", "Ali Jelveh", "Sebastian Roebke"]
@@ -31,7 +31,7 @@ Gem::Specification.new do |s|
31
31
  s.specification_version = 3
32
32
  s.add_runtime_dependency("uuid4r", [">= 0.1.1"])
33
33
  s.add_runtime_dependency("bunny", ["= 0.6.0"])
34
- s.add_runtime_dependency("bunny-ext", [">= 0.6.2"])
34
+ s.add_runtime_dependency("bunny-ext", [">= 0.6.5"])
35
35
  s.add_runtime_dependency("redis", ["= 2.0.4"])
36
36
  s.add_runtime_dependency("amqp", [">= 0.6.7"])
37
37
  s.add_runtime_dependency("activesupport", ["~> 2.3.4"])
@@ -47,7 +47,8 @@ module Beetle
47
47
  # the password to use when connectiong to the AMQP servers (defaults to <tt>"guest"</tt>)
48
48
  attr_accessor :password
49
49
 
50
- # the socket timeout in seconds for message publishing (defaults to <tt>10.0</tt>)
50
+ # the socket timeout in seconds for message publishing (defaults to <tt>0</tt>).
51
+ # consider this a highly experimental feature for now.
51
52
  attr_accessor :publishing_timeout
52
53
 
53
54
  # external config file (defaults to <tt>no file</tt>)
@@ -73,7 +74,7 @@ module Beetle
73
74
  self.user = "guest"
74
75
  self.password = "guest"
75
76
 
76
- self.publishing_timeout = 5.0
77
+ self.publishing_timeout = 0
77
78
 
78
79
  self.log_file = STDOUT
79
80
  end
@@ -44,8 +44,8 @@ module Beetle
44
44
  exchange(exchange_name).publish(data, opts)
45
45
  logger.debug "Beetle: message sent!"
46
46
  published = 1
47
- rescue *bunny_exceptions
48
- stop!
47
+ rescue *bunny_exceptions => e
48
+ stop!(e)
49
49
  tries -= 1
50
50
  # retry same server on receiving the first exception for it (might have been a normal restart)
51
51
  # in this case you'll see either a broken pipe or a forced connection shutdown error
@@ -76,8 +76,8 @@ module Beetle
76
76
  exchange(exchange_name).publish(data, opts)
77
77
  published << @server
78
78
  logger.debug "Beetle: message sent (#{published})!"
79
- rescue *bunny_exceptions
80
- stop!
79
+ rescue *bunny_exceptions => e
80
+ stop!(e)
81
81
  retry if (tries += 1) == 1
82
82
  mark_server_dead
83
83
  end
@@ -120,8 +120,8 @@ module Beetle
120
120
  status = msg[:header].properties[:headers][:status]
121
121
  end
122
122
  logger.debug "Beetle: rpc complete!"
123
- rescue *bunny_exceptions
124
- stop!
123
+ rescue *bunny_exceptions => e
124
+ stop!(e)
125
125
  mark_server_dead
126
126
  tries -= 1
127
127
  retry if tries > 0
@@ -200,10 +200,17 @@ module Beetle
200
200
  queue
201
201
  end
202
202
 
203
- def stop!
203
+ def stop!(exception=nil)
204
204
  begin
205
- bunny.stop
206
- rescue Exception
205
+ Beetle::Timer.timeout(1) do
206
+ if exception
207
+ bunny.__send__ :close_socket
208
+ else
209
+ bunny.stop
210
+ end
211
+ end
212
+ rescue Exception => e
213
+ logger.error "Beetle: error closing down bunny #{e}"
207
214
  Beetle::reraise_expectation_errors!
208
215
  ensure
209
216
  @bunnies[@server] = nil
data/lib/beetle/r_c.rb CHANGED
@@ -4,7 +4,7 @@ module Beetle
4
4
  # message processing result return codes
5
5
  class ReturnCode
6
6
  def initialize(*args)
7
- @recover = args.delete :recover
7
+ @reject = args.delete :reject
8
8
  @failure = args.delete :failure
9
9
  @name = args.first
10
10
  end
@@ -13,8 +13,8 @@ module Beetle
13
13
  @name.blank? ? super : "Beetle::RC::#{@name}"
14
14
  end
15
15
 
16
- def recover?
17
- @recover
16
+ def reject?
17
+ @reject
18
18
  end
19
19
 
20
20
  def failure?
@@ -30,11 +30,11 @@ module Beetle
30
30
  rc :Ancient
31
31
  rc :AttemptsLimitReached, :failure
32
32
  rc :ExceptionsLimitReached, :failure
33
- rc :Delayed, :recover
34
- rc :HandlerCrash, :recover
35
- rc :HandlerNotYetTimedOut, :recover
36
- rc :MutexLocked, :recover
37
- rc :InternalError, :recover
33
+ rc :Delayed, :reject
34
+ rc :HandlerCrash, :reject
35
+ rc :HandlerNotYetTimedOut, :reject
36
+ rc :MutexLocked, :reject
37
+ rc :InternalError, :reject
38
38
  rc :DecodingError, :failure
39
39
 
40
40
  end
@@ -107,9 +107,9 @@ module Beetle
107
107
  message_options = opts.merge(:server => server, :store => @client.deduplication_store)
108
108
  m = Message.new(amqp_queue_name, header, data, message_options)
109
109
  result = m.process(processor)
110
- if result.recover?
110
+ if result.reject?
111
111
  sleep 1
112
- mq(server).recover
112
+ header.reject(:requeue => true)
113
113
  elsif reply_to = header.properties[:reply_to]
114
114
  # require 'ruby-debug'
115
115
  # Debugger.start
@@ -122,9 +122,6 @@ module Beetle
122
122
  Beetle::reraise_expectation_errors!
123
123
  # swallow all exceptions
124
124
  logger.error "Beetle: internal error during message processing: #{$!}: #{$!.backtrace.join("\n")}"
125
- ensure
126
- # support amqp metrics logging if we have it
127
- logger.agent.flush if logger.respond_to?(:agent)
128
125
  end
129
126
  end
130
127
  end
@@ -543,7 +543,7 @@ module Beetle
543
543
  handler.expects(:process_failure).never
544
544
  result = message.process(handler)
545
545
  assert_equal RC::HandlerCrash, result
546
- assert result.recover?
546
+ assert result.reject?
547
547
  assert !result.failure?
548
548
  end
549
549
 
@@ -561,7 +561,7 @@ module Beetle
561
561
  failback.expects(:call).once
562
562
  result = message.process(handler)
563
563
  assert_equal RC::AttemptsLimitReached, result
564
- assert !result.recover?
564
+ assert !result.reject?
565
565
  assert result.failure?
566
566
  end
567
567
 
@@ -578,7 +578,7 @@ module Beetle
578
578
  failback.expects(:call).once
579
579
  result = message.process(handler)
580
580
  assert_equal RC::ExceptionsLimitReached, result
581
- assert !result.recover?
581
+ assert !result.reject?
582
582
  assert result.failure?
583
583
  end
584
584
 
@@ -19,7 +19,7 @@ module Beetle
19
19
  m = mock("dummy")
20
20
  expected_bunny_options = {
21
21
  :host => @pub.send(:current_host), :port => @pub.send(:current_port),
22
- :logging => false, :user => "guest", :pass => "guest", :vhost => "/", :socket_timeout => 5.0
22
+ :logging => false, :user => "guest", :pass => "guest", :vhost => "/", :socket_timeout => 0
23
23
  }
24
24
  Bunny.expects(:new).with(expected_bunny_options).returns(m)
25
25
  m.expects(:start)
@@ -169,15 +169,13 @@ module Beetle
169
169
  assert_nothing_raised { @callback.call(header, 'foo') }
170
170
  end
171
171
 
172
- test "should call recover on the server when processing the handler returns true on recover?" do
172
+ test "should call reject on the message header when processing the handler returns true on recover?" do
173
173
  header = header_with_params({})
174
174
  result = mock("result")
175
- result.expects(:recover?).returns(true)
175
+ result.expects(:reject?).returns(true)
176
176
  Message.any_instance.expects(:process).returns(result)
177
177
  @sub.expects(:sleep).with(1)
178
- mq = mock("MQ")
179
- mq.expects(:recover)
180
- @sub.expects(:mq).with(@sub.server).returns(mq)
178
+ header.expects(:reject).with(:requeue => true)
181
179
  @callback.call(header, 'foo')
182
180
  end
183
181
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beetle
3
3
  version: !ruby/object:Gem::Version
4
- hash: 117
4
+ hash: 107
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
9
  - 9
10
- - 7
11
- version: 0.2.9.7
10
+ - 8
11
+ version: 0.2.9.8
12
12
  platform: ruby
13
13
  authors:
14
14
  - Stefan Kaes
@@ -19,7 +19,7 @@ autorequire:
19
19
  bindir: bin
20
20
  cert_chain: []
21
21
 
22
- date: 2010-12-02 00:00:00 +01:00
22
+ date: 2010-12-13 00:00:00 +01:00
23
23
  default_executable: beetle
24
24
  dependencies:
25
25
  - !ruby/object:Gem::Dependency
@@ -62,12 +62,12 @@ dependencies:
62
62
  requirements:
63
63
  - - ">="
64
64
  - !ruby/object:Gem::Version
65
- hash: 3
65
+ hash: 13
66
66
  segments:
67
67
  - 0
68
68
  - 6
69
- - 2
70
- version: 0.6.2
69
+ - 5
70
+ version: 0.6.5
71
71
  type: :runtime
72
72
  version_requirements: *id003
73
73
  - !ruby/object:Gem::Dependency