Preserve history connections across periodic port rediscovery#1374
Preserve history connections across periodic port rediscovery#1374amilcarlucas merged 10 commits intomasterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR ensures connection entries originating from user history/UI aren’t silently dropped during the periodic (3s) port rediscovery cycle by allowing the frontend to re-merge preserved connections after each scan.
Changes:
- Extend
discover_connections()(protocol + facade + connection manager) to acceptpreserved_connectionsand merge them into the discovered list. - Update the Tkinter connection-selection widget to pass
ProgramSettings.get_connection_history()on each periodic refresh and to persist successful connections duringreconnect(). - Update/extend unit tests to cover preserved-connection behavior and the new method signature forwarding.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
ardupilot_methodic_configurator/frontend_tkinter_connection_selection.py |
Pass preserved history on refresh; persist connected device and register it via add_connection() on successful reconnect. |
ardupilot_methodic_configurator/backend_flightcontroller_protocols.py |
Add preserved_connections to the connection discovery protocol signature. |
ardupilot_methodic_configurator/backend_flightcontroller_connection.py |
Merge caller-supplied preserved connections into the discovered connection tuples. |
ardupilot_methodic_configurator/backend_flightcontroller.py |
Forward preserved_connections through the FlightController facade to the connection manager. |
tests/test_frontend_tkinter_connection_selection.py |
Update periodic-refresh expectations for the new discover_connections() signature and patch history access. |
tests/test_backend_flightcontroller_connection.py |
Add tests verifying preserved connections survive rediscovery and that non-preserved ports disappear. |
tests/test_backend_flightcontroller.py |
Update mock assertion for forwarding preserved_connections=None. |
You can also share your feedback on Copilot code review. Take the survey.
ardupilot_methodic_configurator/frontend_tkinter_connection_selection.py
Outdated
Show resolved
Hide resolved
ardupilot_methodic_configurator/frontend_tkinter_connection_selection.py
Outdated
Show resolved
Hide resolved
ardupilot_methodic_configurator/backend_flightcontroller_connection.py
Outdated
Show resolved
Hide resolved
ardupilot_methodic_configurator/frontend_tkinter_connection_selection.py
Show resolved
Hide resolved
☂️ Python Coverage
Overall Coverage
New FilesNo new covered files... Modified FilesNo covered modified files...
|
a9a33d3 to
abd1d29
Compare
…rmetic tests Address three unresolved code-review issues from PR #1374: - Cache ProgramSettings.get_connection_history() once at widget init as _connection_history_cache instead of calling it (a disk read) on every 3-second periodic port-refresh cycle, preventing potential UI stalls on slow disks or remote home directories. - Update _connection_history_cache in-memory (prepend + deduplicate) in both reconnect() and add_connection() after calling store_connection(), keeping the cache consistent without further disk reads. - Fix reconnect() to persist `selected_connection or device` instead of always persisting self.flight_controller.comport.device. This avoids storing resolved, unstable device paths (e.g. /dev/ttyACM0) when the user explicitly selected a /dev/serial/by-id/* symlink, preventing duplicates in the connection history. - Patch ProgramSettings.store_connection in test_periodic_refresh_stops_on_connection to prevent writes to the real settings.json during tests, and assert the correct connection string was persisted to verify the fix above.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
You can also share your feedback on Copilot code review. Take the survey.
ardupilot_methodic_configurator/backend_flightcontroller_connection.py
Outdated
Show resolved
Hide resolved
ardupilot_methodic_configurator/frontend_tkinter_connection_selection.py
Outdated
Show resolved
Hide resolved
ardupilot_methodic_configurator/frontend_tkinter_connection_selection.py
Outdated
Show resolved
Hide resolved
…discovery The 3-second periodic port refresh rebuilt _connection_tuples entirely from auto-discovered ports, silently dropping any connections that were added from persistent history or via the UI but were not physically present on the bus at that moment. - Add `preserved_connections` parameter to `discover_connections()` so the caller (frontend) can supply history entries to re-merge after each auto-discovery scan, keeping the backend free of settings/filesystem dependencies - Pass `ProgramSettings.get_connection_history()` as `preserved_connections` on every periodic refresh in `ConnectionSelectionWidgets._refresh_ports()` - Store successfully connected device to `ProgramSettings` and register it via `add_connection()` in `reconnect()`, not only when the connection was typed via the "Add another" dialog but also when an existing combobox entry is selected - Update protocol, facade, and tests accordingly
…rmetic tests Address three unresolved code-review issues from PR #1374: - Cache ProgramSettings.get_connection_history() once at widget init as _connection_history_cache instead of calling it (a disk read) on every 3-second periodic port-refresh cycle, preventing potential UI stalls on slow disks or remote home directories. - Update _connection_history_cache in-memory (prepend + deduplicate) in both reconnect() and add_connection() after calling store_connection(), keeping the cache consistent without further disk reads. - Fix reconnect() to persist `selected_connection or device` instead of always persisting self.flight_controller.comport.device. This avoids storing resolved, unstable device paths (e.g. /dev/ttyACM0) when the user explicitly selected a /dev/serial/by-id/* symlink, preventing duplicates in the connection history. - Patch ProgramSettings.store_connection in test_periodic_refresh_stops_on_connection to prevent writes to the real settings.json during tests, and assert the correct connection string was persisted to verify the fix above.
… duplication
- Guard against empty strings and duplicate entries in preserved_connections
by skipping falsy values and updating auto_discovered after each append,
preventing ("", "") tuples and redundant entries in the connection list
- Widen preserved_connections type from list[str] to Sequence[str] across
protocol, facade and connection manager so callers can pass any iterable
without forcing list materialisation
- Extract duplicated store_connection + cache-update logic from
add_connection() and reconnect() into _persist_and_cache_connection(),
centralising edge-case handling in a single place
c5d1766 to
bd7328e
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
You can also share your feedback on Copilot code review. Take the survey.
ardupilot_methodic_configurator/frontend_tkinter_connection_selection.py
Show resolved
Hide resolved
ardupilot_methodic_configurator/frontend_tkinter_connection_selection.py
Show resolved
Hide resolved
…g it would yield individual characters
2755652 to
9a2f72a
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
You can also share your feedback on Copilot code review. Take the survey.
ardupilot_methodic_configurator/frontend_tkinter_connection_selection.py
Outdated
Show resolved
Hide resolved
… in _persist_and_cache_connection Strip whitespace and validate length before updating _connection_history_cache, ensuring the in-memory cache always holds the same normalized value that was persisted. Prevents blank/duplicate entries from surfacing in the combobox and being re-sent as preserved_connections on periodic port refresh.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
ardupilot_methodic_configurator/frontend_tkinter_connection_selection.py:232
_persist_and_cache_connection()normalizes viaProgramSettings.store_connection()butadd_connection()continues to register/select the rawselected_connectionin the backend (add_connection) and the combobox (set_entries_tuple). If the user enters leading/trailing whitespace (allowed by validator; stored stripped), the subsequent refresh will contain the normalized key while the current selection is the raw key, andPairTupleComboboxwill log a critical error when it can't find the selected key. Consider having_persist_and_cache_connection()return the normalized string (or otherwise expose it) and consistently use that normalized value forflight_controller.add_connection(...)and combobox selection updates.
if selected_connection:
self._persist_and_cache_connection(selected_connection)
error_msg = _("Will add new connection: {selected_connection} if not duplicated")
logging_debug(error_msg.format(**locals()))
self.flight_controller.add_connection(selected_connection)
connection_tuples = self.flight_controller.get_connection_tuples()
error_msg = _("Updated connection tuples: {connection_tuples} with selected connection: {selected_connection}")
logging_debug(error_msg.format(**locals()))
self.conn_selection_combobox.set_entries_tuple(connection_tuples, selected_connection)
self.reconnect(selected_connection)
You can also share your feedback on Copilot code review. Take the survey.
ardupilot_methodic_configurator/frontend_tkinter_connection_selection.py
Outdated
Show resolved
Hide resolved
… desync _persist_and_cache_connection() now returns the normalized value (str.strip applied by ProgramSettings.store_connection) instead of None. reconnect() and add_connection() use the returned value for previous_selection and flight_controller.add_connection() so that the in-memory cache, the combobox keys, and the flight controller connection registry all hold the same string. Previously, a user-supplied string with surrounding whitespace (e.g. " COM3 ") was stored as "COM3" but the original padded value was kept as the combobox selection key, causing selection-not-found errors during periodic port rediscovery.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
You can also share your feedback on Copilot code review. Take the survey.
ardupilot_methodic_configurator/frontend_tkinter_connection_selection.py
Outdated
Show resolved
Hide resolved
3d3f27a to
b3efc9d
Compare
…rmetic tests Address three unresolved code-review issues from PR #1374: - Cache ProgramSettings.get_connection_history() once at widget init as _connection_history_cache instead of calling it (a disk read) on every 3-second periodic port-refresh cycle, preventing potential UI stalls on slow disks or remote home directories. - Update _connection_history_cache in-memory (prepend + deduplicate) in both reconnect() and add_connection() after calling store_connection(), keeping the cache consistent without further disk reads. - Fix reconnect() to persist `selected_connection or device` instead of always persisting self.flight_controller.comport.device. This avoids storing resolved, unstable device paths (e.g. /dev/ttyACM0) when the user explicitly selected a /dev/serial/by-id/* symlink, preventing duplicates in the connection history. - Patch ProgramSettings.store_connection in test_periodic_refresh_stops_on_connection to prevent writes to the real settings.json during tests, and assert the correct connection string was persisted to verify the fix above.
The 3-second periodic port refresh rebuilt _connection_tuples entirely from auto-discovered ports, silently dropping any connections that were added from persistent history or via the UI but were not physically present on the bus at that moment.
preserved_connectionsparameter todiscover_connections()so the caller (frontend) can supply history entries to re-merge after each auto-discovery scan, keeping the backend free of settings/filesystem dependenciesProgramSettings.get_connection_history()aspreserved_connectionson every periodic refresh inConnectionSelectionWidgets._refresh_ports()ProgramSettingsand register it viaadd_connection()inreconnect(), not only when the connection was typed via the "Add another" dialog but also when an existing combobox entry is selected