Skip to content

Commit 3969118

Browse files
pawlauvipy
authored andcommitted
reduce memory usage of Connection
1 parent 6917f27 commit 3969118

File tree

2 files changed

+24
-8
lines changed

2 files changed

+24
-8
lines changed

librabbitmq/__init__.py

+14-8
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ def __init__(self, host='localhost', userid='guest', password='guest',
201201
client_properties=client_properties,
202202
)
203203
self.channels = {}
204-
self._avail_channel_ids = array('H', xrange(self.channel_max, 0, -1))
204+
self._used_channel_ids = array('H')
205205
if not lazy:
206206
self.connect()
207207

@@ -247,15 +247,21 @@ def _remove_channel(self, channel):
247247
pass
248248
self.channels.pop(channel.channel_id, None)
249249
self.callbacks.pop(channel.channel_id, None)
250-
self._avail_channel_ids.append(channel.channel_id)
250+
try:
251+
self._used_channel_ids.remove(channel.channel_id)
252+
except ValueError:
253+
# channel id already removed
254+
pass
251255

252256
def _get_free_channel_id(self):
253-
try:
254-
return self._avail_channel_ids.pop()
255-
except IndexError:
256-
raise ConnectionError(
257-
'No free channel ids, current=%d, channel_max=%d' % (
258-
len(self.channels), self.channel_max))
257+
for channel_id in range(1, self.channel_max):
258+
if channel_id not in self._used_channel_ids:
259+
self._used_channel_ids.append(channel_id)
260+
return channel_id
261+
262+
raise ConnectionError(
263+
'No free channel ids, current=%d, channel_max=%d' % (
264+
len(self.channels), self.channel_max))
259265

260266
def close(self):
261267
try:

tests/test_functional.py

+10
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import socket
77
import unittest
8+
from array import array
89

910
from librabbitmq import Message, Connection, ConnectionError, ChannelError
1011
TEST_QUEUE = 'pyrabbit.testq'
@@ -122,6 +123,15 @@ def cb(x):
122123
self.connection.drain_events(timeout=0.1)
123124
self.assertEqual(len(messages), 1)
124125

126+
def test_get_free_channel_id(self):
127+
self.connection._used_channel_ids = array('H')
128+
assert self.connection._get_free_channel_id() == 1
129+
130+
def test_get_free_channel_id__channels_full(self):
131+
self.connection._used_channel_ids = array('H', range(1, self.connection.channel_max))
132+
with self.assertRaises(ConnectionError):
133+
self.connection._get_free_channel_id()
134+
125135
def tearDown(self):
126136
if self.channel and self.connection.connected:
127137
self.channel.queue_purge(TEST_QUEUE)

0 commit comments

Comments
 (0)