Skip to content

fix: resubscribe all topics when session_present=False on connection …#88

Merged
eman merged 3 commits into
mainfrom
fix/mqtt-resubscribe-on-session-lost
May 25, 2026
Merged

fix: resubscribe all topics when session_present=False on connection …#88
eman merged 3 commits into
mainfrom
fix/mqtt-resubscribe-on-session-lost

Conversation

@eman
Copy link
Copy Markdown
Owner

@eman eman commented May 25, 2026

…resume

When the AWS IoT SDK auto-reconnects internally it fires _on_connection_resumed_internal which sets _connected=True. The MqttReconnectionHandler then sees the connection is up and exits its backoff loop without calling resubscribe_all().

With clean_session=True (the library default), session_present is always False on every reconnect -- the broker clears all subscriptions. Without this fix, the client reconnects successfully but has zero active subscriptions, so no device data ever arrives.

Fix: when session_present is False in _on_connection_resumed_internal, schedule resubscribe_all() immediately so topics are restored before any queued commands are sent.

eman and others added 2 commits May 25, 2026 12:37
…resume

When the AWS IoT SDK auto-reconnects internally it fires
_on_connection_resumed_internal which sets _connected=True.  The
MqttReconnectionHandler then sees the connection is up and exits its
backoff loop without calling resubscribe_all().

With clean_session=True (the library default), session_present is always
False on every reconnect -- the broker clears all subscriptions.  Without
this fix, the client reconnects successfully but has zero active
subscriptions, so no device data ever arrives.

Fix: when session_present is False in _on_connection_resumed_internal,
schedule resubscribe_all() immediately so topics are restored before any
queued commands are sent.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a reconnection reliability issue in the MQTT client where AWS IoT SDK internal auto-reconnect can resume a connection with session_present=False (clean session), causing all broker-side subscriptions to be dropped without the client re-subscribing—resulting in no device data being received after reconnect.

Changes:

  • On connection resume, detect session_present=False and proactively trigger resubscribe_all() to restore subscriptions even when the reconnection handler exits early due to _connected=True.

Comment thread src/nwp500/mqtt/client.py
Comment on lines +368 to 389
# previous subscriptions have been dropped server-side. We must
# re-establish them before any device data can flow. This covers the
# common case where the AWS IoT SDK auto-reconnects internally before
# the MqttReconnectionHandler fires its own reconnect path — in that
# scenario the reconnect handler sees _connected==True and exits early,
# so resubscribe_all() would never be called without this block.
if (
not session_present
and self._subscription_manager
and self._connection_manager
and self._connection_manager.connection
):
self._subscription_manager.update_connection(
self._connection_manager.connection
)
self._schedule_coroutine(
self._subscription_manager.resubscribe_all()
)

# Send any queued commands
if self.config.enable_command_queue and self._command_queue:
self._schedule_coroutine(self._send_queued_commands_internal())
Comment thread src/nwp500/mqtt/client.py
Comment on lines +367 to 389
# When the broker starts a clean session (session_present=False), all
# previous subscriptions have been dropped server-side. We must
# re-establish them before any device data can flow. This covers the
# common case where the AWS IoT SDK auto-reconnects internally before
# the MqttReconnectionHandler fires its own reconnect path — in that
# scenario the reconnect handler sees _connected==True and exits early,
# so resubscribe_all() would never be called without this block.
if (
not session_present
and self._subscription_manager
and self._connection_manager
and self._connection_manager.connection
):
self._subscription_manager.update_connection(
self._connection_manager.connection
)
self._schedule_coroutine(
self._subscription_manager.resubscribe_all()
)

# Send any queued commands
if self.config.enable_command_queue and self._command_queue:
self._schedule_coroutine(self._send_queued_commands_internal())
- Fix race condition: ensure resubscribe_all completes before sending
  queued commands when session_present=False
- Create _handle_clean_session_resume() helper method that combines
  subscription restoration with queued command sending in proper order
- Add comprehensive tests for clean session resume behavior in
  test_mqtt_clean_session_resume.py
- Fix pre-existing unreachable code in periodic.py
@eman eman merged commit 1dba609 into main May 25, 2026
7 checks passed
@eman eman deleted the fix/mqtt-resubscribe-on-session-lost branch May 25, 2026 20:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants