hot_bunnies 2.0.0.pre6-java → 2.0.0.pre7-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,9 @@
1
1
  # encoding: utf-8
2
+ require "hot_bunnies/shutdown_listener"
2
3
 
3
4
  module HotBunnies
4
5
  class Channel
5
- attr_reader :session
6
+ attr_reader :session, :consumers
6
7
 
7
8
  def initialize(session, delegate)
8
9
  @connection = session
@@ -12,12 +13,20 @@ module HotBunnies
12
13
  # executors when the channel is closed. This frees library users
13
14
  # from having to worry about this. MK.
14
15
  @consumers = ConcurrentHashMap.new
16
+
17
+ on_shutdown do |ch, cause|
18
+ ch.gracefully_shut_down_consumers
19
+ end
15
20
  end
16
21
 
17
22
  def client
18
23
  @connection
19
24
  end
20
25
 
26
+ def connection
27
+ @connection
28
+ end
29
+
21
30
  def id
22
31
  @delegate.channel_number
23
32
  end
@@ -42,6 +51,12 @@ module HotBunnies
42
51
  v
43
52
  end
44
53
 
54
+ def on_shutdown(&block)
55
+ sh = ShutdownListener.new(self, &block)
56
+ @connection.add_shutdown_listener(sh)
57
+
58
+ sh
59
+ end
45
60
 
46
61
  # @group Exchanges
47
62
 
@@ -297,6 +312,13 @@ module HotBunnies
297
312
  @consumers.delete(consumer_tag)
298
313
  end
299
314
 
315
+ # @private
316
+ def gracefully_shut_down_consumers
317
+ @consumers.each do |tag, consumer|
318
+ consumer.gracefully_shut_down
319
+ end
320
+ end
321
+
300
322
  # Executes a block, catching Java exceptions RabbitMQ Java client throws and
301
323
  # transforms them to Ruby exceptions that are then re-raised.
302
324
  #
@@ -10,6 +10,8 @@ module HotBunnies
10
10
 
11
11
  @cancelling = JavaConcurrent::AtomicBoolean.new
12
12
  @cancelled = JavaConcurrent::AtomicBoolean.new
13
+
14
+ @terminated = JavaConcurrent::AtomicBoolean.new
13
15
  end
14
16
 
15
17
  def handleDelivery(consumer_tag, envelope, properties, body)
@@ -37,11 +39,15 @@ module HotBunnies
37
39
  f.call(@channel, self, consumer_tag)
38
40
  end
39
41
  end
42
+
43
+ @terminated.set(true)
40
44
  end
41
45
 
42
46
  def handleCancelOk(consumer_tag)
43
47
  @cancelled.set(true)
44
48
  @channel.unregister_consumer(consumer_tag)
49
+
50
+ @terminated.set(true)
45
51
  end
46
52
 
47
53
  def start
@@ -55,6 +61,7 @@ module HotBunnies
55
61
  @cancelling.set(true)
56
62
  response = channel.basic_cancel(consumer_tag)
57
63
  @cancelled.set(true)
64
+ @terminated.set(true)
58
65
 
59
66
  response
60
67
  end
@@ -64,7 +71,11 @@ module HotBunnies
64
71
  end
65
72
 
66
73
  def active?
67
- !cancelled?
74
+ !terminated?
75
+ end
76
+
77
+ def terminated?
78
+ @terminated.get
68
79
  end
69
80
  end
70
81
 
@@ -127,6 +138,7 @@ module HotBunnies
127
138
  unless @executor.await_termination(1, JavaConcurrent::TimeUnit::SECONDS)
128
139
  @executor.shutdown_now
129
140
  end
141
+ @terminated.set(true)
130
142
  end
131
143
  alias maybe_shut_down_executor gracefully_shut_down
132
144
  alias gracefully_shutdown gracefully_shut_down
@@ -135,6 +147,8 @@ module HotBunnies
135
147
  class BlockingCallbackConsumer < CallbackConsumer
136
148
  include JavaConcurrent
137
149
 
150
+ POISON = :__poison__
151
+
138
152
  def initialize(channel, buffer_size, opts, callback)
139
153
  super(channel, callback)
140
154
  if buffer_size
@@ -151,7 +165,13 @@ module HotBunnies
151
165
  until (@cancelling.get || @cancelled.get) || JavaConcurrent::Thread.current_thread.interrupted?
152
166
  begin
153
167
  pair = @internal_queue.take
154
- callback(*pair) if pair
168
+ if pair
169
+ if pair == POISON
170
+ @cancelling.set(true)
171
+ else
172
+ callback(*pair)
173
+ end
174
+ end
155
175
  rescue InterruptedException => e
156
176
  interrupted = true
157
177
  end
@@ -159,6 +179,7 @@ module HotBunnies
159
179
  while (pair = @internal_queue.poll)
160
180
  callback(*pair)
161
181
  end
182
+ @terminated.set(true)
162
183
  if interrupted
163
184
  JavaConcurrent::Thread.current_thread.interrupt
164
185
  end
@@ -175,5 +196,13 @@ module HotBunnies
175
196
  end
176
197
  end
177
198
  end
199
+
200
+ def gracefully_shut_down
201
+ @cancelling.set(true)
202
+ @internal_queue.offer(POISON)
203
+
204
+ @terminated.set(true)
205
+ end
206
+
178
207
  end
179
208
  end
@@ -2,6 +2,14 @@ module HotBunnies
2
2
  class Exception < StandardError
3
3
  end
4
4
 
5
+ class ShutdownSignal < Exception
6
+ attr_reader :cause
7
+
8
+ def initialize(cause)
9
+ @cause = cause
10
+ end
11
+ end
12
+
5
13
  class NetworkException < Exception
6
14
  end
7
15
 
@@ -1,3 +1,6 @@
1
+ # encoding: utf-8
2
+ require "hot_bunnies/shutdown_listener"
3
+
1
4
  module HotBunnies
2
5
  java_import com.rabbitmq.client.ConnectionFactory
3
6
  java_import com.rabbitmq.client.Connection
@@ -42,6 +45,8 @@ module HotBunnies
42
45
  new(cf)
43
46
  end
44
47
 
48
+ attr_reader :thread, :channels
49
+
45
50
 
46
51
  def initialize(connection_factory)
47
52
  @cf = connection_factory
@@ -49,6 +54,8 @@ module HotBunnies
49
54
  self.new_connection
50
55
  end
51
56
  @channels = ConcurrentHashMap.new
57
+
58
+ @thread = Thread.current
52
59
  end
53
60
 
54
61
  def create_channel(n = nil)
@@ -72,6 +79,14 @@ module HotBunnies
72
79
  @connection.close
73
80
  end
74
81
 
82
+ def on_shutdown(&block)
83
+ sh = ShutdownListener.new(self, &block)
84
+ @connection.add_shutdown_listener(sh)
85
+
86
+ sh
87
+ end
88
+
89
+
75
90
  def flush
76
91
  @connection.flush
77
92
  end
@@ -84,6 +99,12 @@ module HotBunnies
84
99
  @connection.__send__(selector, *args)
85
100
  end
86
101
 
102
+ # @return [String]
103
+ # @api public
104
+ def to_s
105
+ "#<#{self.class.name}:#{object_id} #{@cf.username}@#{@cf.host}:#{@cf.port}, vhost=#{@cf.virtual_host}>"
106
+ end
107
+
87
108
 
88
109
  #
89
110
  # Implementation
@@ -164,6 +185,8 @@ module HotBunnies
164
185
  block.call
165
186
  rescue java.net.ConnectException => e
166
187
  raise ConnectionRefused.new("Connection to #{@cf.host}:#{@cf.port} refused")
188
+ rescue java.net.UnknownHostException => e
189
+ raise ConnectionRefused.new("Connection to #{@cf.host}:#{@cf.port} refused: host unknown")
167
190
  rescue com.rabbitmq.client.PossibleAuthenticationFailureException => e
168
191
  raise PossibleAuthenticationFailureError.new(@cf.username, @cf.virtual_host, @cf.password.bytesize)
169
192
  end
@@ -0,0 +1,15 @@
1
+ module HotBunnies
2
+ class ShutdownListener
3
+ include com.rabbitmq.client.ShutdownListener
4
+
5
+ def initialize(entity, &block)
6
+ # connection or channel
7
+ @entity = entity
8
+ @block = block
9
+ end
10
+
11
+ def shutdown_completed(cause)
12
+ @block.call(@entity, cause)
13
+ end
14
+ end
15
+ end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module HotBunnies
4
- VERSION = "2.0.0.pre6"
4
+ VERSION = "2.0.0.pre7"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hot_bunnies
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.pre6
4
+ version: 2.0.0.pre7
5
5
  prerelease: 6
6
6
  platform: java
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-07-01 00:00:00.000000000 Z
13
+ date: 2013-07-02 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description: RabbitMQ client for JRuby built around the official RabbitMQ Java client
16
16
  email:
@@ -30,6 +30,7 @@ files:
30
30
  - lib/hot_bunnies/metadata.rb
31
31
  - lib/hot_bunnies/queue.rb
32
32
  - lib/hot_bunnies/session.rb
33
+ - lib/hot_bunnies/shutdown_listener.rb
33
34
  - lib/hot_bunnies/version.rb
34
35
  homepage: http://hotbunnies.info
35
36
  licenses: []