@@ -242,35 +242,62 @@ async def run_ws_sender(
242242 messages : list [str ] = []
243243 try :
244244 while True :
245- # Wait indefinitely for first message, then use timeout for batching
246- timeout = batch_delay if messages else None
247- try :
248- msg = await asyncio .wait_for (q .get (), timeout = timeout )
249- if msg == SHUTDOWN_SIGNAL :
250- if messages :
251- await _send_batched (send_text , messages )
252- return
253- if msg == FLUSH_SIGNAL :
254- if messages :
255- if not await _send_batched (send_text , messages ):
256- return # Connection closed
257- messages = []
258- continue
259- if not batch_delay :
260- try :
261- await send_text (msg )
262- except Exception : # WebSocketDisconnect, RuntimeError, etc.
263- return # Connection closed
264- else :
265- messages .append (msg )
266- except asyncio .TimeoutError :
267- if not await _send_batched (send_text , messages ):
268- return # Connection closed
269- messages = []
245+ result = await _process_ws_message (q , send_text , messages , batch_delay )
246+ if result is False :
247+ return
270248 except asyncio .CancelledError :
271249 pass
272250
273251
252+ async def _process_ws_message (
253+ q : "janus._AsyncQueueProxy[str]" ,
254+ send_text : Callable [[str ], Any ],
255+ messages : list [str ],
256+ batch_delay : float ,
257+ ) -> bool | None :
258+ """Process a single WebSocket message from the queue.
259+
260+ Args:
261+ q: The async queue to read from
262+ send_text: Async function to send text data over WebSocket
263+ messages: List to accumulate messages for batching (mutated in place)
264+ batch_delay: Batch delay in seconds
265+
266+ Returns:
267+ True to continue processing, False to stop the sender loop,
268+ None to continue (same as True but used for continue semantics).
269+ """
270+ timeout = batch_delay if messages else None
271+ try :
272+ msg = await asyncio .wait_for (q .get (), timeout = timeout )
273+ except asyncio .TimeoutError :
274+ if not await _send_batched (send_text , messages ):
275+ return False
276+ messages .clear ()
277+ return True
278+
279+ if msg == SHUTDOWN_SIGNAL :
280+ if messages :
281+ await _send_batched (send_text , messages )
282+ return False
283+
284+ if msg == FLUSH_SIGNAL :
285+ if messages and not await _send_batched (send_text , messages ):
286+ return False
287+ messages .clear ()
288+ return None
289+
290+ if not batch_delay :
291+ try :
292+ await send_text (msg )
293+ except Exception : # pylint: disable=broad-exception-caught
294+ return False # WebSocketDisconnect, RuntimeError, etc.
295+ else :
296+ messages .append (msg )
297+
298+ return True
299+
300+
274301async def _send_batched (send_text : Callable [[str ], Any ], messages : list ) -> bool :
275302 """Send messages as a batch.
276303
@@ -291,8 +318,8 @@ async def _send_batched(send_text: Callable[[str], Any], messages: list) -> bool
291318 # Wrap in array: "[msg1,msg2,msg3]"
292319 await send_text ("[" + "," .join (messages ) + "]" )
293320 return True
294- except Exception : # WebSocketDisconnect, RuntimeError, etc.
295- return False # Connection closed, cleanup handled by main loop
321+ except Exception : # pylint: disable=broad-exception-caught
322+ return False # WebSocketDisconnect, RuntimeError, etc.
296323
297324
298325def make_callback_done_handler (
0 commit comments