From 7889e329ef78bad8f28c67942b50ad9c02ff1a8d Mon Sep 17 00:00:00 2001 From: Stefan Allius Date: Tue, 15 Jul 2025 23:23:35 +0200 Subject: [PATCH] Save a tast reference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Important: Save a reference of the created task, to avoid a task disappearing mid-execution. The event loop only keeps weak references to tasks. A task that isn’t referenced elsewhere may get garbage collected at any time, even before it’s done. For reliable “fire-and-forget” background tasks, gather them in a collection --- app/src/gen3plus/solarman_v5.py | 6 +++++- app/src/inverter_base.py | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/app/src/gen3plus/solarman_v5.py b/app/src/gen3plus/solarman_v5.py index 76d9297..8a82bb2 100755 --- a/app/src/gen3plus/solarman_v5.py +++ b/app/src/gen3plus/solarman_v5.py @@ -327,6 +327,7 @@ class SolarmanV5(SolarmanBase): self.sensor_list = 0 self.mb_regs = [{'addr': 0x3000, 'len': 48}, {'addr': 0x2000, 'len': 96}] + self.background_tasks = set() ''' Our puplic methods @@ -339,6 +340,7 @@ class SolarmanV5(SolarmanBase): self.inverter = None self.switch.clear() self.log_lvl.clear() + self.background_tasks.clear() super().close() def send_start_cmd(self, snr: int, host: str, @@ -690,8 +692,10 @@ class SolarmanV5(SolarmanBase): self.__forward_msg() def publish_mqtt(self, key, data): # pragma: no cover - asyncio.ensure_future( + task = asyncio.ensure_future( Proxy.mqtt.publish(key, data)) + self.background_tasks.add(task) + task.add_done_callback(self.background_tasks.discard) def get_cmd_rsp_log_lvl(self) -> int: ftype = self.ifc.rx_peek()[self.header_len] diff --git a/app/src/inverter_base.py b/app/src/inverter_base.py index d35ddcd..9166100 100644 --- a/app/src/inverter_base.py +++ b/app/src/inverter_base.py @@ -39,6 +39,7 @@ class InverterBase(InverterIfc, Proxy): self.use_emulation = False self.__ha_restarts = -1 self.remote = StreamPtr(None) + self.background_tasks = set() ifc = AsyncStreamServer(reader, writer, self.async_publ_mqtt, self.create_remote, @@ -73,6 +74,7 @@ class InverterBase(InverterIfc, Proxy): if self.remote.ifc: self.remote.ifc.close() self.remote.ifc = None + self.background_tasks.clear() async def disc(self, shutdown_started=False) -> None: if self.remote.stream: @@ -137,7 +139,10 @@ class InverterBase(InverterIfc, Proxy): logging.info(f'[{self.remote.stream.node_id}:' f'{self.remote.stream.conn_no}] ' f'Connected to {addr}') - asyncio.create_task(self.remote.ifc.client_loop(addr)) + task = asyncio.create_task( + self.remote.ifc.client_loop(addr)) + self.background_tasks.add(task) + task.add_done_callback(self.background_tasks.discard) except (ConnectionRefusedError, TimeoutError,