feat: reduce latency to process messages (#161)
Improve `message_bus.py` `_process_message` performance with a `pxd` file
This commit is contained in:
parent
9240bfda6e
commit
113f0c9a32
1
build.py
1
build.py
@ -24,6 +24,7 @@ def build(setup_kwargs):
|
||||
[
|
||||
"src/dbus_fast/aio/message_reader.py",
|
||||
"src/dbus_fast/message.py",
|
||||
"src/dbus_fast/message_bus.py",
|
||||
"src/dbus_fast/signature.py",
|
||||
"src/dbus_fast/unpack.py",
|
||||
"src/dbus_fast/_private/marshaller.py",
|
||||
|
||||
29
src/dbus_fast/message_bus.pxd
Normal file
29
src/dbus_fast/message_bus.pxd
Normal file
@ -0,0 +1,29 @@
|
||||
import cython
|
||||
|
||||
from .message cimport Message
|
||||
|
||||
|
||||
cdef object MessageType
|
||||
cdef object DBusError
|
||||
cdef object MessageFlag
|
||||
|
||||
cdef object MESSAGE_TYPE_CALL
|
||||
cdef object MESSAGE_TYPE_SIGNAL
|
||||
|
||||
cdef class BaseMessageBus:
|
||||
|
||||
cdef public object unique_name
|
||||
cdef public object _disconnected
|
||||
cdef public object _user_disconnect
|
||||
cdef public object _method_return_handlers
|
||||
cdef public object _serial
|
||||
cdef public cython.list _user_message_handlers
|
||||
cdef public object _name_owners
|
||||
cdef public object _bus_address
|
||||
cdef public object _name_owner_match_rule
|
||||
cdef public object _match_rules
|
||||
cdef public object _high_level_client_initialized
|
||||
cdef public object _ProxyObject
|
||||
cdef public object _machine_id
|
||||
|
||||
cpdef _process_message(self, Message msg)
|
||||
@ -25,6 +25,9 @@ from .service import ServiceInterface, _Method
|
||||
from .signature import Variant
|
||||
from .validators import assert_bus_name_valid, assert_object_path_valid
|
||||
|
||||
MESSAGE_TYPE_CALL = MessageType.METHOD_CALL
|
||||
MESSAGE_TYPE_SIGNAL = MessageType.SIGNAL
|
||||
|
||||
|
||||
class BaseMessageBus:
|
||||
"""An abstract class to manage a connection to a DBus message bus.
|
||||
@ -56,6 +59,22 @@ class BaseMessageBus:
|
||||
:vartype connected: bool
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"unique_name",
|
||||
"_disconnected",
|
||||
"_user_disconnect",
|
||||
"_method_return_handlers",
|
||||
"_serial",
|
||||
"_user_message_handlers",
|
||||
"_name_owners",
|
||||
"_bus_address",
|
||||
"_name_owner_match_rule",
|
||||
"_match_rules",
|
||||
"_high_level_client_initialized",
|
||||
"_ProxyObject",
|
||||
"_machine_id",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
bus_address: Optional[str] = None,
|
||||
@ -620,7 +639,7 @@ class BaseMessageBus:
|
||||
if "path" in options:
|
||||
filename = options["path"]
|
||||
elif "abstract" in options:
|
||||
filename = f'\0{options["abstract"]}'
|
||||
filename = b"\0" + options["abstract"].encode()
|
||||
else:
|
||||
raise InvalidAddressError(
|
||||
"got unix transport with unknown path specifier"
|
||||
@ -770,9 +789,8 @@ class BaseMessageBus:
|
||||
|
||||
return SendReply()
|
||||
|
||||
def _process_message(self, msg: Message) -> None:
|
||||
def _process_message(self, msg) -> None:
|
||||
handled = False
|
||||
|
||||
for user_handler in self._user_message_handlers:
|
||||
try:
|
||||
result = user_handler(msg)
|
||||
@ -782,7 +800,7 @@ class BaseMessageBus:
|
||||
handled = True
|
||||
break
|
||||
except DBusError as e:
|
||||
if msg.message_type == MessageType.METHOD_CALL:
|
||||
if msg.message_type is MESSAGE_TYPE_CALL:
|
||||
self.send(e._as_message(msg))
|
||||
handled = True
|
||||
break
|
||||
@ -794,7 +812,7 @@ class BaseMessageBus:
|
||||
logging.error(
|
||||
f"A message handler raised an exception: {e}.\n{traceback.format_exc()}"
|
||||
)
|
||||
if msg.message_type == MessageType.METHOD_CALL:
|
||||
if msg.message_type is MESSAGE_TYPE_CALL:
|
||||
self.send(
|
||||
Message.new_error(
|
||||
msg,
|
||||
@ -805,7 +823,7 @@ class BaseMessageBus:
|
||||
handled = True
|
||||
break
|
||||
|
||||
if msg.message_type == MessageType.SIGNAL:
|
||||
if msg.message_type is MESSAGE_TYPE_SIGNAL:
|
||||
if (
|
||||
msg.member == "NameOwnerChanged"
|
||||
and msg.sender == "org.freedesktop.DBus"
|
||||
@ -817,8 +835,9 @@ class BaseMessageBus:
|
||||
self._name_owners[name] = new_owner
|
||||
elif name in self._name_owners:
|
||||
del self._name_owners[name]
|
||||
return
|
||||
|
||||
elif msg.message_type == MessageType.METHOD_CALL:
|
||||
if msg.message_type is MESSAGE_TYPE_CALL:
|
||||
if not handled:
|
||||
handler = self._find_message_handler(msg)
|
||||
|
||||
@ -835,14 +854,14 @@ class BaseMessageBus:
|
||||
f'{msg.interface}.{msg.member} with signature "{msg.signature}" could not be found',
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
else:
|
||||
# An ERROR or a METHOD_RETURN
|
||||
if msg.reply_serial in self._method_return_handlers:
|
||||
if not handled:
|
||||
return_handler = self._method_return_handlers[msg.reply_serial]
|
||||
return_handler(msg, None)
|
||||
del self._method_return_handlers[msg.reply_serial]
|
||||
# An ERROR or a METHOD_RETURN
|
||||
if msg.reply_serial in self._method_return_handlers:
|
||||
if not handled:
|
||||
return_handler = self._method_return_handlers[msg.reply_serial]
|
||||
return_handler(msg, None)
|
||||
del self._method_return_handlers[msg.reply_serial]
|
||||
|
||||
def _make_method_handler(
|
||||
self, interface: ServiceInterface, method: _Method
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user