From 88d485911ab0c317b30cb7f8c173aa4afab5239f Mon Sep 17 00:00:00 2001 From: denpamusic Date: Sat, 21 Oct 2023 03:36:31 +0300 Subject: [PATCH] Improve device entry handling. - Add small LRU cache for device handler and name getter, since it's called on every received frame. - Separate entry creating routine into it's own function. --- pyplumio/devices/__init__.py | 4 +++- pyplumio/protocol.py | 19 +++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/pyplumio/devices/__init__.py b/pyplumio/devices/__init__.py index 079519d7..25dbc55e 100644 --- a/pyplumio/devices/__init__.py +++ b/pyplumio/devices/__init__.py @@ -2,6 +2,7 @@ from __future__ import annotations import asyncio +from functools import lru_cache import logging from typing import ClassVar @@ -43,10 +44,11 @@ def get_device_handler(device_type: int) -> str: raise UnknownDeviceError(f"Unknown device ({device_type})") +@lru_cache(maxsize=5) def get_device_handler_and_name(device_type: int) -> tuple[str, str]: """Get device handler full path and lowercased class name.""" handler = get_device_handler(device_type) - _, class_name = handler.rsplit(".", 1) + class_name = handler.rsplit(".", 1)[1] return handler, class_name.lower() diff --git a/pyplumio/protocol.py b/pyplumio/protocol.py index ec84151d..f8b49632 100644 --- a/pyplumio/protocol.py +++ b/pyplumio/protocol.py @@ -143,18 +143,21 @@ async def shutdown(self): def setup_device_entry(self, device_type: DeviceType) -> Addressable: """Setup the device entry.""" handler, name = get_device_handler_and_name(device_type) - write_queue: asyncio.Queue = self.queues[1] + if name not in self.data: - device: Addressable = factory( - handler, queue=write_queue, network=self._network - ) - device.dispatch_nowait(ATTR_CONNECTED, True) - self.create_task(device.async_setup()) - self.data[name] = device - self.set_event(name) + self._create_device_entry(name, handler) return self.data[name] + def _create_device_entry(self, name: str, handler: str) -> None: + """Create the device entry.""" + write_queue = self.queues[1] + device: Addressable = factory(handler, queue=write_queue, network=self._network) + device.dispatch_nowait(ATTR_CONNECTED, True) + self.create_task(device.async_setup()) + self.data[name] = device + self.set_event(name) + async def _remove_writer(self): """Attempt to gracefully remove the frame writer.""" if self.writer: