Hallo zusammen,
beim Beenden bzw. Neustarten von SmartHomeNG erscheinen bei mir regelmäßig folgende Meldungen:
und, wenn SHNG im Vordergrund unter systemd läuft (stderr im Journal):
Umgebung: SmartHomeNG v1.11.0-master (388aae606), Python 3.10.13, Raspberry Pi 5, Debian 12. Die Stelle ist im aktuellen master unverändert.
Ursache (modules/websocket/__init__.py, _ws_server_thread(), finally-Block):
Lösungsvorschlag für den finally-Block:
Ich habe das Verhalten mit einem kleinen Testskript nachgestellt (Event-Loop im Thread, run_forever(), Stopp per call_soon_threadsafe(loop.stop), ein Endlos-Task und ein Async-Generator). Der bisherige Code erzeugt genau beide Meldungen, mit der Änderung gibt es keine Meldung mehr, und der Generator wird ordentlich aufgeräumt.
Mir ist aufgefallen, dass run_until_complete(self.loop.shutdown_asyncgens()) im Code als Kommentar schon steht. Falls es einen Grund gab, das nicht zu verwenden, etwa ein Hängen beim Beenden, wäre ich für einen Hinweis dankbar.
Die Meldungen sind harmlos, das Beenden funktioniert. Sie tauchen aber bei jedem Neustart im Warnungs-Log auf und verwirren bei der Fehlersuche.
Vielleicht hat ja auch einer von euch Kontakt zu den Entwicklern - wäre cool.
Viele Grüße
Günther
beim Beenden bzw. Neustarten von SmartHomeNG erscheinen bei mir regelmäßig folgende Meldungen:
Code:
ERROR asyncio Task was destroyed but it is pending! task: <Task pending name='update_all_series' coro=<Protocol.update_all_series() running at .../modules/websocket/smartvisu.py:617> ...> ERROR asyncio Task was destroyed but it is pending! task: <Task pending name='update_all_series' coro=<Protocol.update_all_series() running at .../modules/websocket/admin.py:576> ...>
Code:
modules/websocket/__init__.py:256: RuntimeWarning: coroutine 'BaseEventLoop.shutdown_asyncgens' was never awaited self.loop.shutdown_asyncgens()
Ursache (modules/websocket/__init__.py, _ws_server_thread(), finally-Block):
- self.loop.shutdown_asyncgens() ist eine Coroutine. Sie wird nur erzeugt, aber nie ausgeführt. Daher die RuntimeWarning, und die Async-Generatoren werden nicht aufgeräumt.
- Die noch laufenden Tasks (z. B. update_all_series der Protokolle smartvisu und admin) werden vor self.loop.close() nicht abgebrochen. Beim Schließen der Loop sind sie noch „pending“, daher „Task was destroyed but it is pending!“.
Lösungsvorschlag für den finally-Block:
Code:
try:
self.loop.run_forever()
finally:
try:
# noch laufende Tasks (z.B. update_all_series) sauber abbrechen
pending = asyncio.all_tasks(self.loop)
for task in pending:
task.cancel()
if pending:
self.loop.run_until_complete(asyncio.gather(*pending, return_exceptions=True))
# Coroutine muss ausgefuehrt werden, nicht nur aufgerufen
self.loop.run_until_complete(self.loop.shutdown_asyncgens())
except Exception as e:
self.logger.warning(f'_ws_server_thread: finally - Exception on shutdown: {e}')
try:
self.loop.close()
except Exception as e:
self.logger.warning(f'_ws_server_thread: finally - Exception on loop.close(): {e}')
Mir ist aufgefallen, dass run_until_complete(self.loop.shutdown_asyncgens()) im Code als Kommentar schon steht. Falls es einen Grund gab, das nicht zu verwenden, etwa ein Hängen beim Beenden, wäre ich für einen Hinweis dankbar.
Die Meldungen sind harmlos, das Beenden funktioniert. Sie tauchen aber bei jedem Neustart im Warnungs-Log auf und verwirren bei der Fehlersuche.
Vielleicht hat ja auch einer von euch Kontakt zu den Entwicklern - wäre cool.
Viele Grüße
Günther


aber danke für dein Feedback, es ist schön zu sehen, dass sich immer noch Leute finden, die sich Gedanken darum machen, shng zu verbessern 
Kommentar