Check for empty messages and handle thread-safety
This commit is contained in:
1 parent
0330fe4e62
commit
5567d67305
1 file changed
+23
-4
@@ -2,6 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import threading
|
||||
from abc import abstractmethod
|
||||
from collections.abc import Iterable
|
||||
from typing import TYPE_CHECKING, List, Optional
|
||||
@@ -36,7 +37,9 @@ class APIServer(asyncio.Protocol):
|
||||
self._pos: int = 0
|
||||
self._transport = None
|
||||
self._writelines = None
|
||||
|
||||
self._loop: Optional[asyncio.AbstractEventLoop] = None
|
||||
self._loop_thread_id: Optional[int] = None
|
||||
|
||||
@abstractmethod
|
||||
def handle_message(self, msg: message.Message) -> Iterable[message.Message]:
|
||||
pass
|
||||
@@ -75,7 +78,7 @@ class APIServer(asyncio.Protocol):
|
||||
self.send_messages(msgs)
|
||||
|
||||
def send_messages(self, msgs: List[message.Message]):
|
||||
if self._writelines is None:
|
||||
if self._writelines is None or not msgs:
|
||||
return
|
||||
|
||||
packets = [
|
||||
@@ -83,12 +86,26 @@ class APIServer(asyncio.Protocol):
|
||||
for msg in msgs
|
||||
]
|
||||
packet_bytes = make_plain_text_packets(packets)
|
||||
if (
|
||||
self._loop is not None
|
||||
and self._loop_thread_id is not None
|
||||
and threading.get_ident() != self._loop_thread_id
|
||||
):
|
||||
self._loop.call_soon_threadsafe(self._writelines, packet_bytes)
|
||||
return
|
||||
|
||||
self._writelines(packet_bytes)
|
||||
|
||||
def connection_made(self, transport) -> None:
|
||||
self._transport = transport
|
||||
self._writelines = transport.writelines
|
||||
|
||||
try:
|
||||
self._loop = asyncio.get_running_loop()
|
||||
except RuntimeError:
|
||||
self._loop = None
|
||||
else:
|
||||
self._loop_thread_id = threading.get_ident()
|
||||
|
||||
def data_received(self, data: bytes):
|
||||
if self._buffer is None:
|
||||
self._buffer = data
|
||||
@@ -141,7 +158,9 @@ class APIServer(asyncio.Protocol):
|
||||
def connection_lost(self, exc):
|
||||
self._transport = None
|
||||
self._writelines = None
|
||||
|
||||
self._loop = None
|
||||
self._loop_thread_id = None
|
||||
|
||||
def _read_varuint(self) -> int:
|
||||
"""Read a varuint from the buffer or -1 if the buffer runs out of bytes."""
|
||||
if not self._buffer:
|
||||
|
||||
Reference in new issue
Block a user