amqp 1.1.5 → 1.1.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c75b12b09ec783fd8d5b1e953b2ad36d348401f7
4
- data.tar.gz: 3a2e57b606aa0563c2b94ff911a4fd32cacac18a
3
+ metadata.gz: 480856b9abfa322113dabee60f290c0763e80691
4
+ data.tar.gz: 20c5d50f24be734b8f45261d10c608aea26cb005
5
5
  SHA512:
6
- metadata.gz: f7956da40b93fb3aca23c1a3c318c9bc343761e4bf2265019957dfb48a8a482284fc52118fa4b5dea46b9b8ac6b4d0fbc8af76d1605cc6b3d7921dd148af8688
7
- data.tar.gz: 87f9aa52d4ccbbec0cf3893d62534a6bf4f6c31facc379c19b555b6010cf258b663462ccd0026ee0b45338ed22d499a324e99d89f13d0d3fd718831ea9525c9b
6
+ metadata.gz: 3942ea6fea956c33bf53e531acab4c9fea1e6366e14483b935550c125b4db7217e45c677e650b85db67ed92810b77dcd730cdaf6c9b8e6ba2af1d1e725d398d4
7
+ data.tar.gz: ebf78c68c6a188c5d7583dd93c5213d52d82671845650b76b6dabf3743dd4b69b1c06257a85e6294bdc8df69a144539b74306e15c341b9a4737a6203b866e11d
@@ -20,6 +20,7 @@ notifications:
20
20
  branches:
21
21
  only:
22
22
  - master
23
+ - 1.1.x-stable
23
24
  - 1.0.x-stable
24
25
  matrix:
25
26
  allow_failures:
@@ -1,6 +1,34 @@
1
+ ## Changes Between 1.1.5 and 1.1.6
2
+
3
+ ### 65535 Channels Per Connection
4
+
5
+ amqp gem now allows for 65535 channels per connection and
6
+ not Ruby process.
7
+
8
+ Contributed by Neo (http://neo.com) developers.
9
+
10
+
11
+ ## Changes Between 1.1.4 and 1.1.5
12
+
13
+ ### channel.close is Delayed Until After Channel is Open
14
+
15
+ This eliminates a race condition in some codebases that use
16
+ very short lived channels.
17
+
18
+
19
+ ## Changes Between 1.1.3 and 1.1.4
20
+
21
+ ### ConnectionClosedError is Back
22
+
23
+ `ConnectionClosedError` is now defined again.
24
+
25
+
1
26
  ## Changes Between 1.1.2 and 1.1.3
2
27
 
3
- No changes yet.
28
+ ### Fixed Exception in AMQP::Exchange#handle_declare_ok
29
+
30
+ `AMQP::Exchange#handle_declare_ok` no longer raises an exception
31
+ about undefined method.
4
32
 
5
33
 
6
34
  ## Changes Between 1.1.1 and 1.1.2
@@ -231,19 +231,19 @@ module AMQP
231
231
  #
232
232
  # @see AMQP::Channel#prefetch
233
233
  # @api public
234
- def initialize(connection = nil, id = self.class.next_channel_id, options = {}, &block)
234
+ def initialize(connection = nil, id = nil, options = {}, &block)
235
235
  raise 'AMQP can only be used from within EM.run {}' unless EM.reactor_running?
236
236
 
237
237
  @connection = connection || AMQP.connection || AMQP.start
238
238
  # this means 2nd argument is options
239
239
  if id.kind_of?(Hash)
240
240
  options = options.merge(id)
241
- id = self.class.next_channel_id
241
+ id = @connection.next_channel_id
242
242
  end
243
243
 
244
244
  super(@connection)
245
245
 
246
- @id = id
246
+ @id = id || @connection.next_channel_id
247
247
  @exchanges = Hash.new
248
248
  @queues = Hash.new
249
249
  @consumers = Hash.new
@@ -264,8 +264,8 @@ module AMQP
264
264
  65536
265
265
  end
266
266
 
267
- if channel_max != 0 && !(0..channel_max).include?(id)
268
- raise ArgumentError.new("Max channel for the connection is #{channel_max}, given: #{id}")
267
+ if channel_max != 0 && !(0..channel_max).include?(@id)
268
+ raise ArgumentError.new("Max channel for the connection is #{channel_max}, given: #{@id}")
269
269
  end
270
270
 
271
271
  # we need this deferrable to mimic what AMQP gem 0.7 does to enable
@@ -344,7 +344,7 @@ module AMQP
344
344
  # must release after we allocate a new id, otherwise we will end up
345
345
  # with the same value. MK.
346
346
  @id = self.class.next_channel_id
347
- self.class.release_channel_id(old_id)
347
+ @connection.release_channel_id(old_id)
348
348
 
349
349
  @channel_is_open_deferrable.fail
350
350
  @channel_is_open_deferrable = AMQP::Deferrable.new
@@ -1174,67 +1174,10 @@ module AMQP
1174
1174
  self.exec_callback_yielding_self(:after_connection_interruption)
1175
1175
  self.reset_state!
1176
1176
 
1177
- self.class.release_channel_id(@id) unless auto_recovering?
1177
+ @connection.release_channel_id(@id) unless auto_recovering?
1178
1178
  @channel_is_open_deferrable = AMQP::Deferrable.new
1179
1179
  end
1180
1180
 
1181
-
1182
- # @private
1183
- # @api private
1184
- def self.channel_id_mutex
1185
- @channel_id_mutex ||= Mutex.new
1186
- end
1187
-
1188
- # Returns next available channel id. This method is thread safe.
1189
- #
1190
- # @return [Fixnum]
1191
- # @api public
1192
- # @see Channel.release_channel_id
1193
- # @see Channel.reset_channel_id_allocator
1194
- def self.next_channel_id
1195
- channel_id_mutex.synchronize do
1196
- self.initialize_channel_id_allocator
1197
-
1198
- @int_allocator.allocate
1199
- end
1200
- end
1201
-
1202
- # Releases previously allocated channel id. This method is thread safe.
1203
- #
1204
- # @param [Fixnum] Channel id to release
1205
- # @api public
1206
- # @see Channel.next_channel_id
1207
- # @see Channel.reset_channel_id_allocator
1208
- def self.release_channel_id(i)
1209
- channel_id_mutex.synchronize do
1210
- self.initialize_channel_id_allocator
1211
-
1212
- @int_allocator.release(i)
1213
- end
1214
- end # self.release_channel_id(i)
1215
-
1216
- # Resets channel allocator. This method is thread safe.
1217
- # @api public
1218
- # @see Channel.next_channel_id
1219
- # @see Channel.release_channel_id
1220
- def self.reset_channel_id_allocator
1221
- channel_id_mutex.synchronize do
1222
- initialize_channel_id_allocator
1223
-
1224
- @int_allocator.reset
1225
- end
1226
- end # self.reset_channel_id_allocator
1227
-
1228
-
1229
- # @private
1230
- def self.initialize_channel_id_allocator
1231
- # TODO: ideally, this should be in agreement with agreed max number of channels of the connection,
1232
- # but it is possible that value either not yet available. MK.
1233
- max_channel = (1 << 16) - 1
1234
- @int_allocator ||= IntAllocator.new(1, max_channel)
1235
- end # self.initialize_channel_id_allocator
1236
-
1237
-
1238
1181
  # @return [Boolean] true if this channel uses automatic recovery mode
1239
1182
  def auto_recovering?
1240
1183
  @auto_recovery
@@ -1534,7 +1477,7 @@ module AMQP
1534
1477
  self.connection.clear_frames_on(self.id)
1535
1478
  self.exec_callback_once_yielding_self(:close, close_ok)
1536
1479
 
1537
- self.class.release_channel_id(@id)
1480
+ @connection.release_channel_id(@id)
1538
1481
  end
1539
1482
 
1540
1483
  # @api plugin
@@ -0,0 +1,58 @@
1
+ module AMQP
2
+ module ChannelIdAllocator
3
+
4
+ MAX_CHANNELS_PER_CONNECTION = (2**16)
5
+
6
+ # Resets channel allocator. This method is thread safe.
7
+ # @api public
8
+ # @see Channel.next_channel_id
9
+ # @see Channel.release_channel_id
10
+ def reset_channel_id_allocator
11
+ channel_id_mutex.synchronize do
12
+ int_allocator.reset
13
+ end
14
+ end
15
+
16
+ # Releases previously allocated channel id. This method is thread safe.
17
+ #
18
+ # @param [Fixnum] Channel id to release
19
+ # @api public
20
+ # @see Channel.next_channel_id
21
+ # @see Channel.reset_channel_id_allocator
22
+ def release_channel_id(i)
23
+ channel_id_mutex.synchronize do
24
+ int_allocator.release(i)
25
+ end
26
+ end
27
+
28
+ # Returns next available channel id. This method is thread safe.
29
+ #
30
+ # @return [Fixnum]
31
+ # @api public
32
+ # @see Channel.release_channel_id
33
+ # @see Channel.reset_channel_id_allocator
34
+ def next_channel_id
35
+ channel_id_mutex.synchronize do
36
+ result = int_allocator.allocate
37
+ raise "No further channels available. Please open a new connection." if result < 0
38
+ result
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ # @private
45
+ # @api private
46
+ def channel_id_mutex
47
+ @channel_id_mutex ||= Mutex.new
48
+ end
49
+
50
+ # @private
51
+ def int_allocator
52
+ # TODO: ideally, this should be in agreement with agreed max number of channels of the connection,
53
+ # but it is possible that value either not yet available. MK.
54
+ @int_allocator ||= IntAllocator.new(1, MAX_CHANNELS_PER_CONNECTION)
55
+ end
56
+
57
+ end
58
+ end
@@ -6,6 +6,7 @@ require "amqp/auth_mechanism_adapter"
6
6
  require "amqp/broker"
7
7
 
8
8
  require "amqp/channel"
9
+ require "amqp/channel_id_allocator"
9
10
 
10
11
  module AMQP
11
12
  # AMQP session represents connection to the broker. Session objects let you define callbacks for
@@ -33,7 +34,7 @@ module AMQP
33
34
  #
34
35
  # @api public
35
36
  class Session < EM::Connection
36
-
37
+ include AMQP::ChannelIdAllocator
37
38
 
38
39
  #
39
40
  # Behaviours
@@ -6,5 +6,5 @@ module AMQP
6
6
  #
7
7
  # @see AMQ::Protocol::VERSION
8
8
  # @return [String] AMQP gem version
9
- VERSION = '1.1.5'
9
+ VERSION = '1.1.6'
10
10
  end
@@ -46,7 +46,7 @@ describe AMQP::Channel, "options hash" do
46
46
 
47
47
 
48
48
  it "can be passed as the 3rd constructor argument" do
49
- ch = AMQP::Channel.new(AMQP.connection, AMQP::Channel.next_channel_id, :auto_recovery => true)
49
+ ch = AMQP::Channel.new(AMQP.connection, nil, :auto_recovery => true)
50
50
  ch.auto_recovery.should be_true
51
51
  ch.auto_recovery = false
52
52
  ch.auto_recovery.should be_false
@@ -1,40 +1,60 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require "spec_helper"
4
+ describe AMQP::ChannelIdAllocator do
4
5
 
5
- describe AMQP::Channel do
6
- describe ".next_channel_id" do
7
- before :all do
8
- described_class.reset_channel_id_allocator
6
+ class ChannelAllocator
7
+ include AMQP::ChannelIdAllocator
8
+ end
9
+
10
+ describe "#next_channel_id" do
11
+ subject do
12
+ ChannelAllocator.new()
9
13
  end
10
14
 
11
15
  context "when there is a channel id available for allocation" do
12
16
  it "returns that channel id" do
13
- 1024.times { described_class.next_channel_id }
17
+ 1024.times { subject.next_channel_id }
14
18
 
15
- described_class.next_channel_id.should == 1025
19
+ subject.next_channel_id.should == 1025
16
20
  end
17
21
  end
18
22
 
19
23
  context "when THERE IS NOT channel id available for allocation" do
20
- it "raises an exception"
24
+ it "raises an exception" do
25
+ (ChannelAllocator::MAX_CHANNELS_PER_CONNECTION - 1).times do
26
+ subject.next_channel_id
27
+ end
28
+
29
+ lambda { subject.next_channel_id }.should raise_error
30
+ end
21
31
  end
22
32
  end
23
33
 
24
34
 
25
-
26
35
  describe ".release_channel_id" do
27
- before :all do
28
- described_class.reset_channel_id_allocator
36
+ subject do
37
+ ChannelAllocator.new()
29
38
  end
30
39
 
31
40
  it "releases that channel id" do
32
- 1024.times { described_class.next_channel_id }
33
- described_class.next_channel_id.should == 1025
41
+ 1024.times { subject.next_channel_id }
42
+ subject.next_channel_id.should == 1025
43
+
44
+ subject.release_channel_id(128)
45
+ subject.next_channel_id.should == 128
46
+ subject.next_channel_id.should == 1026
47
+ end
48
+ end
34
49
 
35
- described_class.release_channel_id(128)
36
- described_class.next_channel_id.should == 128
37
- described_class.next_channel_id.should == 1026
50
+ describe "each instance gets its own channel IDs" do
51
+ it "has an allocator per instance" do
52
+ one = ChannelAllocator.new()
53
+ two = ChannelAllocator.new()
54
+ one.next_channel_id.should == 1
55
+ one.next_channel_id.should == 2
56
+ two.next_channel_id.should == 1
57
+ two.next_channel_id.should == 2
38
58
  end
39
59
  end
40
- end
60
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: amqp
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.5
4
+ version: 1.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aman Gupta
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-11-26 00:00:00.000000000 Z
13
+ date: 2013-12-09 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: eventmachine
@@ -234,6 +234,7 @@ files:
234
234
  - lib/amqp/broker.rb
235
235
  - lib/amqp/callbacks.rb
236
236
  - lib/amqp/channel.rb
237
+ - lib/amqp/channel_id_allocator.rb
237
238
  - lib/amqp/compatibility/ruby187_patchlevel_check.rb
238
239
  - lib/amqp/consumer.rb
239
240
  - lib/amqp/consumer_tag_generator.rb
@@ -298,11 +299,9 @@ files:
298
299
  - spec/integration/tx_commit_spec.rb
299
300
  - spec/integration/tx_rollback_spec.rb
300
301
  - spec/spec_helper.rb
301
- - spec/unit/amqp/bit_set_spec.rb
302
302
  - spec/unit/amqp/channel_id_allocation_spec.rb
303
303
  - spec/unit/amqp/client_spec.rb
304
304
  - spec/unit/amqp/connection_spec.rb
305
- - spec/unit/amqp/int_allocator_spec.rb
306
305
  homepage: http://rubyamqp.info
307
306
  licenses:
308
307
  - Ruby
@@ -1,127 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- require "amqp/bit_set"
6
-
7
-
8
- describe AMQP::BitSet do
9
-
10
- #
11
- # Environment
12
- #
13
-
14
- let(:nbits) { (1 << 16) - 1 }
15
-
16
-
17
- #
18
- # Examples
19
- #
20
-
21
- describe "#get, #[]" do
22
- describe "when bit at given position is set" do
23
- subject do
24
- o = described_class.new(nbits)
25
- o.set(3)
26
- o
27
- end
28
-
29
- it "returns true" do
30
- subject.get(3).should be_true
31
- end # it
32
- end # describe
33
-
34
- describe "when bit at given position is off" do
35
- subject do
36
- described_class.new(nbits)
37
- end
38
-
39
- it "returns false" do
40
- subject.get(5).should be_false
41
- end # it
42
- end # describe
43
- end # describe
44
-
45
-
46
- describe "#set" do
47
- describe "when bit at given position is set" do
48
- subject do
49
- described_class.new(nbits)
50
- end
51
-
52
- it "has no effect" do
53
- subject.set(3)
54
- subject.get(3).should be_true
55
- subject.set(3)
56
- subject[3].should be_true
57
- end # it
58
- end
59
-
60
- describe "when bit at given position is off" do
61
- subject do
62
- described_class.new(nbits)
63
- end
64
-
65
- it "sets that bit" do
66
- subject.set(3)
67
- subject.get(3).should be_true
68
-
69
- subject.set(33)
70
- subject.get(33).should be_true
71
-
72
- subject.set(3387)
73
- subject.get(3387).should be_true
74
- end
75
- end # describe
76
- end # describe
77
-
78
-
79
- describe "#unset" do
80
- describe "when bit at a given position is set" do
81
- subject do
82
- described_class.new(nbits)
83
- end
84
-
85
- it "unsets that bit" do
86
- subject.set(3)
87
- subject.get(3).should be_true
88
- subject.unset(3)
89
- subject.get(3).should be_false
90
- end # it
91
- end # describe
92
-
93
-
94
- describe "when bit at a given position is off" do
95
- subject do
96
- described_class.new(nbits)
97
- end
98
-
99
- it "has no effect" do
100
- subject.get(3).should be_false
101
- subject.unset(3)
102
- subject.get(3).should be_false
103
- end # it
104
- end # describe
105
- end # describe
106
-
107
-
108
-
109
- describe "#clear" do
110
- subject do
111
- described_class.new(nbits)
112
- end
113
-
114
- it "clears all bits" do
115
- subject.set(3)
116
- subject.get(3).should be_true
117
-
118
- subject.set(7668)
119
- subject.get(7668).should be_true
120
-
121
- subject.clear
122
-
123
- subject.get(3).should be_false
124
- subject.get(7668).should be_false
125
- end
126
- end
127
- end
@@ -1,116 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
- require "amqp/int_allocator"
5
-
6
- describe AMQP::IntAllocator do
7
-
8
- #
9
- # Environment
10
- #
11
-
12
- subject do
13
- described_class.new(1, 5)
14
- end
15
-
16
-
17
- # ...
18
-
19
-
20
- #
21
- # Examples
22
- #
23
-
24
- describe "#number_of_bits" do
25
- it "returns number of bits available for allocation" do
26
- subject.number_of_bits.should == 4
27
- end
28
- end
29
-
30
-
31
- describe "#hi" do
32
- it "returns upper bound of the allocation range" do
33
- subject.hi.should == 5
34
- end
35
- end
36
-
37
- describe "#lo" do
38
- it "returns lower bound of the allocation range" do
39
- subject.lo.should == 1
40
- end
41
- end
42
-
43
-
44
- describe "#allocate" do
45
- context "when integer in the range is available" do
46
- it "returns allocated integer" do
47
- subject.allocate.should == 1
48
- subject.allocate.should == 2
49
- subject.allocate.should == 3
50
- subject.allocate.should == 4
51
-
52
- subject.allocate.should == -1
53
- end
54
- end
55
-
56
- context "when integer in the range IS NOT available" do
57
- it "returns -1" do
58
- 4.times { subject.allocate }
59
-
60
- subject.allocate.should == -1
61
- subject.allocate.should == -1
62
- subject.allocate.should == -1
63
- subject.allocate.should == -1
64
- end
65
- end
66
- end
67
-
68
-
69
- describe "#free" do
70
- context "when the integer WAS allocated" do
71
- it "returns frees that integer" do
72
- 4.times { subject.allocate }
73
- subject.allocate.should == -1
74
-
75
- subject.free(1)
76
- subject.allocate.should == 1
77
- subject.allocate.should == -1
78
- subject.free(2)
79
- subject.allocate.should == 2
80
- subject.allocate.should == -1
81
- subject.free(3)
82
- subject.allocate.should == 3
83
- subject.allocate.should == -1
84
- end
85
- end
86
-
87
- context "when the integer WAS NOT allocated" do
88
- it "has no effect" do
89
- 32.times { subject.free(1) }
90
- subject.allocate.should == 1
91
- end
92
- end
93
- end
94
-
95
-
96
- describe "#allocated?" do
97
- context "when given position WAS allocated" do
98
- it "returns true" do
99
- 3.times { subject.allocate }
100
-
101
- subject.allocated?(1).should be_true
102
- subject.allocated?(2).should be_true
103
- subject.allocated?(3).should be_true
104
- end
105
- end
106
-
107
- context "when given position WAS NOT allocated" do
108
- it "returns false" do
109
- 2.times { subject.allocate }
110
-
111
- subject.allocated?(3).should be_false
112
- subject.allocated?(4).should be_false
113
- end
114
- end
115
- end
116
- end