Skip to content

Commit 7cd9045

Browse files
pawlauvipy
authored andcommitted
improve performance of _get_free_channel_id, fix channel max bug
1 parent 0f5e23c commit 7cd9045

File tree

2 files changed

+28
-10
lines changed

2 files changed

+28
-10
lines changed

librabbitmq/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,11 @@ def _remove_channel(self, channel):
255255
pass
256256

257257
def _get_free_channel_id(self):
258-
for channel_id in range(1, self.channel_max):
259-
if channel_id not in self._used_channel_ids:
258+
# Cast to a set for fast lookups, and keep stored as an array for lower memory usage.
259+
used_channel_ids = set(self._used_channel_ids)
260+
261+
for channel_id in range(1, self.channel_max + 1):
262+
if channel_id not in used_channel_ids:
260263
self._used_channel_ids.append(channel_id)
261264
return channel_id
262265

tests/test_functional.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,24 @@ def test_connection_timeout(self):
4444
self.assertGreaterEqual(took_time, 2)
4545
self.assertLessEqual(took_time, 4)
4646

47+
def test_get_free_channel_id(self):
48+
with Connection() as connection:
49+
assert connection._get_free_channel_id() == 1
50+
assert connection._get_free_channel_id() == 2
51+
52+
def test_get_free_channel_id__channels_full(self):
53+
with Connection() as connection:
54+
for _ in range(connection.channel_max):
55+
connection._get_free_channel_id()
56+
with self.assertRaises(ConnectionError):
57+
connection._get_free_channel_id()
58+
59+
def test_channel(self):
60+
with Connection() as connection:
61+
self.assertEqual(connection._used_channel_ids, array('H'))
62+
connection.channel()
63+
self.assertEqual(connection._used_channel_ids, array('H', (1,)))
64+
4765

4866
class test_Channel(unittest.TestCase):
4967

@@ -157,14 +175,11 @@ def cb(x):
157175
self.connection.drain_events(timeout=0.1)
158176
self.assertEqual(len(messages), 1)
159177

160-
def test_get_free_channel_id(self):
161-
self.connection._used_channel_ids = array('H')
162-
assert self.connection._get_free_channel_id() == 1
163-
164-
def test_get_free_channel_id__channels_full(self):
165-
self.connection._used_channel_ids = array('H', range(1, self.connection.channel_max))
166-
with self.assertRaises(ConnectionError):
167-
self.connection._get_free_channel_id()
178+
def test_close(self):
179+
self.assertEqual(self.connection._used_channel_ids, array('H', (1,)))
180+
self.channel.close()
181+
self.channel = None
182+
self.assertEqual(self.connection._used_channel_ids, array('H'))
168183

169184
def tearDown(self):
170185
if self.channel and self.connection.connected:

0 commit comments

Comments
 (0)