Skip to content

Commit bb2c8d4

Browse files
knmarcinBBooijLiewes
authored andcommitted
Close RabbitMQ connection after publishing to prevent file descriptor leaks
1 parent abd8c3b commit bb2c8d4

File tree

4 files changed

+45
-14
lines changed

4 files changed

+45
-14
lines changed

binder/websocket.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,24 @@ def list_rooms_for_user(self, user):
3232

3333
def trigger(data, rooms):
3434
if 'rabbitmq' in getattr(settings, 'HIGH_TEMPLAR', {}):
35-
import pika
36-
from pika import BlockingConnection
37-
38-
connection_credentials = pika.PlainCredentials(settings.HIGH_TEMPLAR['rabbitmq']['username'],
39-
settings.HIGH_TEMPLAR['rabbitmq']['password'])
40-
connection_parameters = pika.ConnectionParameters(settings.HIGH_TEMPLAR['rabbitmq']['host'],
41-
credentials=connection_credentials)
42-
connection = BlockingConnection(parameters=connection_parameters)
43-
channel = connection.channel()
44-
45-
channel.basic_publish('hightemplar', routing_key='*', body=jsondumps({
46-
'data': data,
47-
'rooms': rooms,
48-
}))
35+
connection = None
36+
try:
37+
import pika
38+
from pika import BlockingConnection
39+
connection_credentials = pika.PlainCredentials(settings.HIGH_TEMPLAR['rabbitmq']['username'],
40+
settings.HIGH_TEMPLAR['rabbitmq']['password'])
41+
connection_parameters = pika.ConnectionParameters(settings.HIGH_TEMPLAR['rabbitmq']['host'],
42+
credentials=connection_credentials)
43+
connection = BlockingConnection(parameters=connection_parameters)
44+
channel = connection.channel()
45+
46+
channel.basic_publish('hightemplar', routing_key='*', body=jsondumps({
47+
'data': data,
48+
'rooms': rooms,
49+
}))
50+
finally:
51+
if connection and not connection.is_closed:
52+
connection.close()
4953
if getattr(settings, 'HIGH_TEMPLAR_URL', None):
5054
url = getattr(settings, 'HIGH_TEMPLAR_URL')
5155
try:

ci-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ codecov
88
coverage
99
django-hijack<3.0.0
1010
openpyxl
11+
pika

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
'Pillow >= 3.2.0',
4141
'django-request-id >= 1.0.0',
4242
'requests >= 2.13.0',
43+
'pika == 1.3.2',
4344
],
4445
tests_require=[
4546
'django-hijack >= 2.1.10, < 3.0.0',

tests/test_websocket.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from django.contrib.auth.models import User
33
from unittest import mock
44
from binder.views import JsonResponse
5+
from binder.websocket import trigger
56
from .testapp.urls import room_controller
67
from .testapp.models import Animal, Costume
78
import requests
@@ -68,3 +69,27 @@ def test_post_succeeds_when_trigger_fails(self):
6869
costume.save()
6970

7071
self.assertIsNotNone(costume.pk)
72+
73+
74+
class TriggerConnectionCloseTest(TestCase):
75+
@override_settings(
76+
HIGH_TEMPLAR={
77+
'rabbitmq': {
78+
'host': 'localhost',
79+
'username': 'guest',
80+
'password': 'guest'
81+
}
82+
}
83+
)
84+
@mock.patch('pika.BlockingConnection')
85+
def test_trigger_calls_connection_close(self, mock_connection_class):
86+
mock_connection = mock_connection_class.return_value
87+
mock_connection.is_closed = False
88+
89+
data = {'id': 123}
90+
rooms = [{'costume': 123}]
91+
92+
trigger(data, rooms)
93+
94+
mock_connection.close.assert_called_once()
95+

0 commit comments

Comments
 (0)