Skip to content

Commit 8d7059a

Browse files
Properly handle callbacks in multi-host configurations
Fixes #150
1 parent 06e7cec commit 8d7059a

File tree

3 files changed

+15
-13
lines changed

3 files changed

+15
-13
lines changed

socketio/asyncio_manager.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,9 @@ async def trigger_callback(self, sid, namespace, id, data):
4848
else:
4949
del self.callbacks[sid][namespace][id]
5050
if callback is not None:
51-
if asyncio.iscoroutinefunction(callback) is True:
51+
ret = callback(*data)
52+
if asyncio.iscoroutine(ret):
5253
try:
53-
await callback(*data)
54+
await ret
5455
except asyncio.CancelledError: # pragma: no cover
5556
pass
56-
else:
57-
callback(*data)

socketio/pubsub_manager.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ def emit(self, event, data, namespace=None, room=None, skip_sid=None,
6363
callback = None
6464
self._publish({'method': 'emit', 'event': event, 'data': data,
6565
'namespace': namespace, 'room': room,
66-
'skip_sid': skip_sid, 'callback': callback})
66+
'skip_sid': skip_sid, 'callback': callback,
67+
'host_id': self.host_id})
6768

6869
def close_room(self, room, namespace=None):
6970
self._publish({'method': 'close_room', 'room': room,
@@ -93,8 +94,9 @@ def _handle_emit(self, message):
9394
# Here in the receiving end we set up a local callback that preserves
9495
# the callback host and id from the sender
9596
remote_callback = message.get('callback')
97+
remote_host_id = message.get('host_id')
9698
if remote_callback is not None and len(remote_callback) == 3:
97-
callback = partial(self._return_callback, self.host_id,
99+
callback = partial(self._return_callback, remote_host_id,
98100
*remote_callback)
99101
else:
100102
callback = None

tests/test_pubsub_manager.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ def setUp(self):
1717
self.pm = pubsub_manager.PubSubManager()
1818
self.pm._publish = mock.MagicMock()
1919
self.pm.set_server(mock_server)
20+
self.pm.host_id = '123456'
2021
self.pm.initialize()
2122

2223
def test_default_init(self):
2324
self.assertEqual(self.pm.channel, 'socketio')
24-
self.assertEqual(len(self.pm.host_id), 32)
2525
self.pm.server.start_background_task.assert_called_once_with(
2626
self.pm._thread)
2727

@@ -44,28 +44,28 @@ def test_emit(self):
4444
self.pm._publish.assert_called_once_with(
4545
{'method': 'emit', 'event': 'foo', 'data': 'bar',
4646
'namespace': '/', 'room': None, 'skip_sid': None,
47-
'callback': None})
47+
'callback': None, 'host_id': '123456'})
4848

4949
def test_emit_with_namespace(self):
5050
self.pm.emit('foo', 'bar', namespace='/baz')
5151
self.pm._publish.assert_called_once_with(
5252
{'method': 'emit', 'event': 'foo', 'data': 'bar',
5353
'namespace': '/baz', 'room': None, 'skip_sid': None,
54-
'callback': None})
54+
'callback': None, 'host_id': '123456'})
5555

5656
def test_emit_with_room(self):
5757
self.pm.emit('foo', 'bar', room='baz')
5858
self.pm._publish.assert_called_once_with(
5959
{'method': 'emit', 'event': 'foo', 'data': 'bar',
6060
'namespace': '/', 'room': 'baz', 'skip_sid': None,
61-
'callback': None})
61+
'callback': None, 'host_id': '123456'})
6262

6363
def test_emit_with_skip_sid(self):
6464
self.pm.emit('foo', 'bar', skip_sid='baz')
6565
self.pm._publish.assert_called_once_with(
6666
{'method': 'emit', 'event': 'foo', 'data': 'bar',
6767
'namespace': '/', 'room': None, 'skip_sid': 'baz',
68-
'callback': None})
68+
'callback': None, 'host_id': '123456'})
6969

7070
def test_emit_with_callback(self):
7171
with mock.patch.object(self.pm, '_generate_ack_id',
@@ -74,7 +74,7 @@ def test_emit_with_callback(self):
7474
self.pm._publish.assert_called_once_with(
7575
{'method': 'emit', 'event': 'foo', 'data': 'bar',
7676
'namespace': '/', 'room': 'baz', 'skip_sid': None,
77-
'callback': ('baz', '/', '123')})
77+
'callback': ('baz', '/', '123'), 'host_id': '123456'})
7878

7979
def test_emit_with_callback_without_server(self):
8080
standalone_pm = pubsub_manager.PubSubManager()
@@ -141,7 +141,8 @@ def test_handle_emit_with_callback(self):
141141
with mock.patch.object(base_manager.BaseManager, 'emit') as super_emit:
142142
self.pm._handle_emit({'event': 'foo', 'data': 'bar',
143143
'namespace': '/baz',
144-
'callback': ('sid', '/baz', 123)})
144+
'callback': ('sid', '/baz', 123),
145+
'host_id': host_id})
145146
self.assertEqual(super_emit.call_count, 1)
146147
self.assertEqual(super_emit.call_args[0], ('foo', 'bar'))
147148
self.assertEqual(super_emit.call_args[1]['namespace'], '/baz')

0 commit comments

Comments
 (0)