Skip to content

Commit 919f4d9

Browse files
committed
Fix RuntimeError: no running event loop in MQTT reconnection
- Fixed RuntimeError when _on_connection_interrupted_internal tries to create reconnection task from MQTT callback thread without event loop - Fixed RuntimeWarning about _reconnect_with_backoff coroutine never being awaited - Added _start_reconnect_task() helper method to properly create tasks within event loop - Uses existing _schedule_coroutine() for thread-safe task scheduling - Prevents crashes during automatic reconnection after connection interruptions Fixes issue seen in Home Assistant logs: RuntimeError: no running event loop RuntimeWarning: coroutine '_reconnect_with_backoff' was never awaited
1 parent 265cc0a commit 919f4d9

2 files changed

Lines changed: 21 additions & 1 deletion

File tree

CHANGELOG.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,16 @@ Changed
205205
Fixed
206206
-----
207207

208+
- **Critical Bug**: Thread-safe reconnection task creation from MQTT callbacks
209+
210+
- Fixed ``RuntimeError: no running event loop`` when connection is interrupted
211+
- Fixed ``RuntimeWarning: coroutine '_reconnect_with_backoff' was never awaited``
212+
- Connection interruption callbacks run in separate threads without event loops
213+
- Implemented ``_start_reconnect_task()`` helper method to properly create reconnection tasks
214+
- Uses existing ``_schedule_coroutine()`` method for thread-safe task scheduling
215+
- Prevents crashes during automatic reconnection after connection interruptions
216+
- Ensures reconnection tasks are properly awaited and executed
217+
208218
- **Critical Bug**: Thread-safe event emission from MQTT callbacks
209219

210220
- Fixed ``RuntimeError: no running event loop in thread 'Dummy-1'``

src/nwp500/mqtt_client.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ def _on_connection_interrupted_internal(self, connection, error, **kwargs):
273273
and (not self._reconnect_task or self._reconnect_task.done())
274274
):
275275
_logger.info("Starting automatic reconnection...")
276-
self._reconnect_task = asyncio.create_task(self._reconnect_with_backoff())
276+
self._schedule_coroutine(self._start_reconnect_task())
277277

278278
def _on_connection_resumed_internal(self, connection, return_code, session_present, **kwargs):
279279
"""Internal handler for connection resumption."""
@@ -299,6 +299,16 @@ def _on_connection_resumed_internal(self, connection, return_code, session_prese
299299
if self.config.enable_command_queue:
300300
self._schedule_coroutine(self._send_queued_commands())
301301

302+
async def _start_reconnect_task(self):
303+
"""
304+
Start the reconnect task within the event loop.
305+
306+
This is a helper method to create the reconnect task from within
307+
a coroutine that's scheduled via _schedule_coroutine.
308+
"""
309+
if not self._reconnect_task or self._reconnect_task.done():
310+
self._reconnect_task = asyncio.create_task(self._reconnect_with_backoff())
311+
302312
async def _reconnect_with_backoff(self):
303313
"""
304314
Attempt to reconnect with exponential backoff.

0 commit comments

Comments
 (0)