Skip to content

Commit d972ca3

Browse files
Document concurrency problems with emits (Fixes #403)
1 parent 01378ef commit d972ca3

File tree

4 files changed

+53
-3
lines changed

4 files changed

+53
-3
lines changed

socketio/asyncio_client.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,13 @@ async def emit(self, event, data=None, namespace=None, callback=None):
148148
by the client. Callback functions can only be used
149149
when addressing an individual client.
150150
151-
Note: this method is a coroutine.
151+
Note: this method is not designed to be used concurrently. If multiple
152+
tasks are emitting at the same time on the same client connection, then
153+
messages composed of multiple packets may end up being sent in an
154+
incorrect sequence. Use standard concurrency solutions (such as a Lock
155+
object) to prevent this situation.
156+
157+
Note 2: this method is a coroutine.
152158
"""
153159
namespace = namespace or '/'
154160
if namespace != '/' and namespace not in self.namespaces:
@@ -214,7 +220,13 @@ async def call(self, event, data=None, namespace=None, timeout=60):
214220
the client acknowledges the event, then a
215221
``TimeoutError`` exception is raised.
216222
217-
Note: this method is a coroutine.
223+
Note: this method is not designed to be used concurrently. If multiple
224+
tasks are emitting at the same time on the same client connection, then
225+
messages composed of multiple packets may end up being sent in an
226+
incorrect sequence. Use standard concurrency solutions (such as a Lock
227+
object) to prevent this situation.
228+
229+
Note 2: this method is a coroutine.
218230
"""
219231
callback_event = self.eio.create_event()
220232
callback_args = []

socketio/asyncio_server.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,13 @@ async def emit(self, event, data=None, to=None, room=None, skip_sid=None,
118118
to always leave this parameter with its default
119119
value of ``False``.
120120
121-
Note: this method is a coroutine.
121+
Note: this method is not designed to be used concurrently. If multiple
122+
tasks are emitting at the same time to the same client connection, then
123+
messages composed of multiple packets may end up being sent in an
124+
incorrect sequence. Use standard concurrency solutions (such as a Lock
125+
object) to prevent this situation.
126+
127+
Note 2: this method is a coroutine.
122128
"""
123129
namespace = namespace or '/'
124130
room = to or room
@@ -194,6 +200,14 @@ async def call(self, event, data=None, to=None, sid=None, namespace=None,
194200
single server process is used. It is recommended
195201
to always leave this parameter with its default
196202
value of ``False``.
203+
204+
Note: this method is not designed to be used concurrently. If multiple
205+
tasks are emitting at the same time to the same client connection, then
206+
messages composed of multiple packets may end up being sent in an
207+
incorrect sequence. Use standard concurrency solutions (such as a Lock
208+
object) to prevent this situation.
209+
210+
Note 2: this method is a coroutine.
197211
"""
198212
if not self.async_handlers:
199213
raise RuntimeError(

socketio/client.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,12 @@ def emit(self, event, data=None, namespace=None, callback=None):
311311
that will be passed to the function are those provided
312312
by the client. Callback functions can only be used
313313
when addressing an individual client.
314+
315+
Note: this method is not thread safe. If multiple threads are emitting
316+
at the same time on the same client connection, messages composed of
317+
multiple packets may end up being sent in an incorrect sequence. Use
318+
standard concurrency solutions (such as a Lock object) to prevent this
319+
situation.
314320
"""
315321
namespace = namespace or '/'
316322
if namespace != '/' and namespace not in self.namespaces:
@@ -373,6 +379,12 @@ def call(self, event, data=None, namespace=None, timeout=60):
373379
:param timeout: The waiting timeout. If the timeout is reached before
374380
the client acknowledges the event, then a
375381
``TimeoutError`` exception is raised.
382+
383+
Note: this method is not thread safe. If multiple threads are emitting
384+
at the same time on the same client connection, messages composed of
385+
multiple packets may end up being sent in an incorrect sequence. Use
386+
standard concurrency solutions (such as a Lock object) to prevent this
387+
situation.
376388
"""
377389
callback_event = self.eio.create_event()
378390
callback_args = []

socketio/server.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,12 @@ def emit(self, event, data=None, to=None, room=None, skip_sid=None,
280280
single server process is used. It is recommended
281281
to always leave this parameter with its default
282282
value of ``False``.
283+
284+
Note: this method is not thread safe. If multiple threads are emitting
285+
at the same time to the same client, then messages composed of
286+
multiple packets may end up being sent in an incorrect sequence. Use
287+
standard concurrency solutions (such as a Lock object) to prevent this
288+
situation.
283289
"""
284290
namespace = namespace or '/'
285291
room = to or room
@@ -352,6 +358,12 @@ def call(self, event, data=None, to=None, sid=None, namespace=None,
352358
single server process is used. It is recommended
353359
to always leave this parameter with its default
354360
value of ``False``.
361+
362+
Note: this method is not thread safe. If multiple threads are emitting
363+
at the same time to the same client, then messages composed of
364+
multiple packets may end up being sent in an incorrect sequence. Use
365+
standard concurrency solutions (such as a Lock object) to prevent this
366+
situation.
355367
"""
356368
if not self.async_handlers:
357369
raise RuntimeError(

0 commit comments

Comments
 (0)