Skip to content

Fix: Double session initialization#647

Open
hdd wants to merge 1 commit into
mainfrom
backlog/double-session
Open

Fix: Double session initialization#647
hdd wants to merge 1 commit into
mainfrom
backlog/double-session

Conversation

@hdd
Copy link
Copy Markdown
Collaborator

@hdd hdd commented May 28, 2026

Summary by CodeRabbit

  • Bug Fixes

    • Improved error message formatting for startup and login failures, providing clearer feedback
    • Enhanced session management for increased reliability
  • Improvements

    • About dialog now displays plugin information with compatibility status tags
    • Refined plugin discovery and loading process with better error handling
    • Updated theme application

Review Change Stack

@hdd hdd requested a review from dennisweil May 28, 2026 15:11
@hdd hdd requested a review from a team as a code owner May 28, 2026 15:12
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 28, 2026

📝 Walkthrough

Walkthrough

The pull request modernizes the Connect application file with extensive style updates (docstrings, string quotes, f-strings) alongside behavioral improvements: explicit session cleanup during reconfiguration, refactored plugin discovery with compatibility logic, and enhanced about-dialog debug information with compatibility tagging.

Changes

Connect Application Modernization and Session Management

Layer / File(s) Summary
Class definitions and Application initialization
apps/connect/source/ftrack_connect/ui/application.py
ConnectWidgetPlugin and ConnectWidget base classes updated with docstrings and style changes; Application initialization now includes a plugins property accessor and reformatted logging.
Application restart and lifecycle management
apps/connect/source/ftrack_connect/ui/application.py
Restart method refactored to explicitly distinguish frozen vs. non-frozen environments with improved argv handling and f-string logging; window object naming and system tray setup updated.
Theme configuration and application
apps/connect/source/ftrack_connect/ui/application.py
Theme methods updated with docstrings; _set_theme now applies a full theme via applyTheme() instead of font-only approach; system theme fallback and usage tracking metadata refactored.
Login and credential management
apps/connect/source/ftrack_connect/ui/application.py
_save_credentials ensures id key exists and structures accounts as a list; login entry point and credential overlay messaging refactored.
Session creation and error handling
apps/connect/source/ftrack_connect/ui/application.py
_setup_session and plugin path computation updated; _report_session_setup_error formats messages with HTML breaks; loginWithCredentials modernized with environment variable handling and API communication.
Session reconfiguration with explicit cleanup
apps/connect/source/ftrack_connect/ui/application.py
_location_configuration_finished now explicitly closes any existing self._session before reconfiguration with guarded exception handling around event hub disconnect and session cleanup; verify-startup UI updated.
Plugin discovery and selection refactoring
apps/connect/source/ftrack_connect/ui/application.py
New _gather_plugins helper extracts directory search and hook loading logic; _available_plugin_data_from_plugin_directories reorganized to deduplicate case-insensitively and prefer compatible/latest versions.
Event routing and plugin lifecycle management
apps/connect/source/ftrack_connect/ui/application.py
Event relaying and menu creation updated; _route_event extracts plugin/action from payload; _discover_connect_widgets uses explicit error handling and continue paths; _add_plugin and _remove_plugin preserve lifecycle signal wiring.
About dialog and debug information assembly
apps/connect/source/ftrack_connect/ui/application.py
Debug information assembly collects environment, application-launcher, and widget plugin data; raw responses merged by plugin name; entries tagged with compatibility status (Incompatible/Deprecated/Ignored) and sorted before display.
Window state and built-in widget configuration
apps/connect/source/ftrack_connect/ui/application.py
Focus and always-on-top window flag logic updated; _configure_action_launcher_widget and _configure_plugin_manager_widget refactored with docstrings and environment variable handling; closeEvent updated.

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request has no description provided, missing all required template sections including purpose, scope, implementation details, testing, and issue tracking. Add a comprehensive PR description following the template, including issue tracking (CLICKUP/FT/SENTRY/ZENDESK), testing checklist, overview, implementation details, and notes for reviewers.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change—fixing double session initialization—which aligns with the primary behavior-impacting change in the diff.
Docstring Coverage ✅ Passed Docstring coverage is 87.50% which is sufficient. The required threshold is 50.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch backlog/double-session

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

Coverage report

This PR does not seem to contain any modification to coverable code.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/connect/source/ftrack_connect/ui/application.py (1)

217-225: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Guard restart cleanup when instance is not provided.

Line [221] and Line [224] dereference self._instance even though __init__ accepts instance=None. Triggering restart in that state will raise before relaunch.

Suggested fix
     def restart(self):
         """restart connect application"""
         self.logger.info("Connect restarting....")
         QtWidgets.QApplication.quit()
-        self._instance.__del__()
+        if self._instance is not None:
+            self._instance.__del__()
 
         # Give enough time to ensure the lockfile has been removed
-        while os.path.exists(self._instance.lockfile):
+        lockfile = getattr(self._instance, "lockfile", None)
+        while lockfile and os.path.exists(lockfile):
             time.sleep(0.1)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/connect/source/ftrack_connect/ui/application.py` around lines 217 - 225,
The restart method dereferences self._instance without guarding for None
(__init__ can set instance=None); update restart to check that self._instance is
truthy before calling self._instance.__del__ and before accessing
self._instance.lockfile in the while loop (e.g., if self._instance: ...), so
that restart safely no-ops cleanup when no instance was provided.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/connect/source/ftrack_connect/ui/application.py`:
- Around line 798-800: The code compares raw version strings
(current_dir_plugin["version"] and plugin["version"]) lexically, causing
incorrect ordering (e.g., "10" < "2"); replace the direct string comparison with
a version-aware comparison by parsing both versions with a proper version parser
(e.g., packaging.version.parse or packaging.version.Version) and then compare
the parsed versions; update the import and change the comparison expression used
where current_dir_plugin and plugin version values are compared so the newer
plugin is chosen reliably.
- Around line 1075-1079: The loop over self._widget_plugin_instances is
iterating dictionary keys rather than widget instances so isinstance(plugin,
ConnectWidget) always fails; change the iteration to loop over the actual values
(widget instances) and then append plugin.get_debug_information() for each
ConnectWidget instance—specifically update the loop that references
self._widget_plugin_instances and the isinstance check against ConnectWidget and
calls to get_debug_information() so it inspects the plugin objects (e.g., for
plugin in self._widget_plugin_instances.values() or equivalent) instead of keys.
- Line 654: The inline implementation comment contains a temporal marker "NEW:";
remove the "NEW:" prefix and rewrite the comment so it reads as a timeless
instruction (e.g., "Properly close the existing session before creating a new
one") near the session-creation/teardown logic (the comment attached to the
session cleanup and recreation code), ensuring no draft/history markers remain
and the comment is concise and permanent.
- Around line 449-451: The login overlay message passed to CancelOverlay uses a
malformed closing tag ("<h2/>"); update the message string in the creation of
self._login_overlay (CancelOverlay(..., message=...)) to use a properly closed
heading tag (e.g., "<h2>Signing in</h2>") so the HTML is valid and renders
consistently.

---

Outside diff comments:
In `@apps/connect/source/ftrack_connect/ui/application.py`:
- Around line 217-225: The restart method dereferences self._instance without
guarding for None (__init__ can set instance=None); update restart to check that
self._instance is truthy before calling self._instance.__del__ and before
accessing self._instance.lockfile in the while loop (e.g., if self._instance:
...), so that restart safely no-ops cleanup when no instance was provided.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 841b3aa0-9b7f-4f68-9e8c-073752bda5d8

📥 Commits

Reviewing files that changed from the base of the PR and between be2f8ab and 1160d9f.

📒 Files selected for processing (1)
  • apps/connect/source/ftrack_connect/ui/application.py

Comment on lines 449 to 451
self._login_overlay = ftrack_connect.ui.widget.overlay.CancelOverlay(
self._login_widget, message='<h2>Signing in<h2/>'
self._login_widget, message="<h2>Signing in<h2/>"
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix malformed heading HTML in login overlay message.

Line [450] closes h2 incorrectly (<h2/>), which can render inconsistently.

Suggested fix
         self._login_overlay = ftrack_connect.ui.widget.overlay.CancelOverlay(
-            self._login_widget, message="<h2>Signing in<h2/>"
+            self._login_widget, message="<h2>Signing in</h2>"
         )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
self._login_overlay = ftrack_connect.ui.widget.overlay.CancelOverlay(
self._login_widget, message='<h2>Signing in<h2/>'
self._login_widget, message="<h2>Signing in<h2/>"
)
self._login_overlay = ftrack_connect.ui.widget.overlay.CancelOverlay(
self._login_widget, message="<h2>Signing in</h2>"
)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/connect/source/ftrack_connect/ui/application.py` around lines 449 - 451,
The login overlay message passed to CancelOverlay uses a malformed closing tag
("<h2/>"); update the message string in the creation of self._login_overlay
(CancelOverlay(..., message=...)) to use a properly closed heading tag (e.g.,
"<h2>Signing in</h2>") so the HTML is valid and renders consistently.

self.logger.exception("Failed to disconnect from event hub.")
pass

# NEW: Properly close the existing session before creating a new one
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove temporal marker from implementation comment.

Line [654] uses NEW, which is draft-history residue and will stale over time.

Suggested fix
-        # NEW: Properly close the existing session before creating a new one
+        # Close the existing session before creating a new one.

As per coding guidelines, implementation code/comments must stand on their own and should not include temporal references like prior-step or draft markers.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# NEW: Properly close the existing session before creating a new one
# Close the existing session before creating a new one.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/connect/source/ftrack_connect/ui/application.py` at line 654, The inline
implementation comment contains a temporal marker "NEW:"; remove the "NEW:"
prefix and rewrite the comment so it reads as a timeless instruction (e.g.,
"Properly close the existing session before creating a new one") near the
session-creation/teardown logic (the comment attached to the session cleanup and
recreation code), ensuring no draft/history markers remain and the comment is
concise and permanent.

Comment on lines +798 to 800
current_dir_plugin["version"]
< plugin["version"]
):
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Version selection uses lexical comparison instead of version-aware ordering.

Line [798]-Line [800] compares raw version values directly, which can choose the wrong “latest” plugin (e.g., "10" vs "2").

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/connect/source/ftrack_connect/ui/application.py` around lines 798 - 800,
The code compares raw version strings (current_dir_plugin["version"] and
plugin["version"]) lexically, causing incorrect ordering (e.g., "10" < "2");
replace the direct string comparison with a version-aware comparison by parsing
both versions with a proper version parser (e.g., packaging.version.parse or
packaging.version.Version) and then compare the parsed versions; update the
import and change the comparison expression used where current_dir_plugin and
plugin version values are compared so the newer plugin is chosen reliably.

Comment on lines 1075 to 1079
for plugin in self._widget_plugin_instances:
if isinstance(plugin, ConnectWidget):
debug_information['widgets'].append(
debug_information["widgets"].append(
plugin.get_debug_information()
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Widget debug info loop iterates keys, not widget instances.

This loop iterates dict keys, so isinstance(plugin, ConnectWidget) is always false and widget debug info is silently skipped.

Suggested fix
-        for plugin in self._widget_plugin_instances:
+        for plugin in self._widget_plugin_instances.values():
             if isinstance(plugin, ConnectWidget):
                 debug_information["widgets"].append(
                     plugin.get_debug_information()
                 )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/connect/source/ftrack_connect/ui/application.py` around lines 1075 -
1079, The loop over self._widget_plugin_instances is iterating dictionary keys
rather than widget instances so isinstance(plugin, ConnectWidget) always fails;
change the iteration to loop over the actual values (widget instances) and then
append plugin.get_debug_information() for each ConnectWidget
instance—specifically update the loop that references
self._widget_plugin_instances and the isinstance check against ConnectWidget and
calls to get_debug_information() so it inspects the plugin objects (e.g., for
plugin in self._widget_plugin_instances.values() or equivalent) instead of keys.

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.

1 participant