Skip to content

Commit

Permalink
improve performance of _get_free_channel_id, fix channel max bug (cel…
Browse files Browse the repository at this point in the history
…ery#385)

* improve performance of _get_free_channel_id, fix channel max bug

* add integration tests for _get_free_channel_id performance improvement
  • Loading branch information
pawl authored Dec 22, 2021
1 parent 81d4072 commit 935a06b
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 4 deletions.
7 changes: 5 additions & 2 deletions amqp/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,8 +482,11 @@ def collect(self):
self._transport = self.connection = self.channels = None

def _get_free_channel_id(self):
for channel_id in range(1, self.channel_max):
if channel_id not in self._used_channel_ids:
# Cast to a set for fast lookups, and keep stored as an array for lower memory usage.
used_channel_ids = set(self._used_channel_ids)

for channel_id in range(1, self.channel_max + 1):
if channel_id not in used_channel_ids:
self._used_channel_ids.append(channel_id)
return channel_id

Expand Down
4 changes: 4 additions & 0 deletions t/integration/test_integration.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import socket
from array import array
from struct import pack
from unittest.mock import ANY, Mock, call, patch

Expand Down Expand Up @@ -534,9 +535,11 @@ def test_channel_open_close(self):
frame_writer_mock.reset_mock()

on_open_mock = Mock()
assert conn._used_channel_ids == array('H')
ch = conn.channel(channel_id=channel_id, callback=on_open_mock)
on_open_mock.assert_called_once_with(ch)
assert ch.is_open is True
assert conn._used_channel_ids == array('H', (1,))

ch.close()
frame_writer_mock.assert_has_calls(
Expand All @@ -552,6 +555,7 @@ def test_channel_open_close(self):
]
)
assert ch.is_open is False
assert conn._used_channel_ids == array('H')

def test_received_channel_Close_during_connection_close(self):
# This test verifies that library handles correctly closing channel
Expand Down
6 changes: 4 additions & 2 deletions t/unit/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,10 @@ def test_get_free_channel_id(self):
assert self.conn._get_free_channel_id() == 1
assert self.conn._get_free_channel_id() == 2

def test_get_free_channel_id__raises_IndexError(self):
self.conn._used_channel_ids = array('H', range(1, self.conn.channel_max))
def test_get_free_channel_id__raises_ResourceError(self):
self.conn.channel_max = 2
self.conn._get_free_channel_id()
self.conn._get_free_channel_id()
with pytest.raises(ResourceError):
self.conn._get_free_channel_id()

Expand Down

0 comments on commit 935a06b

Please sign in to comment.