Skip to content

Execute logout tasks in background#85

Open
thierryskoda wants to merge 1 commit intomainfrom
cursor/execute-logout-tasks-in-background-39db
Open

Execute logout tasks in background#85
thierryskoda wants to merge 1 commit intomainfrom
cursor/execute-logout-tasks-in-background-39db

Conversation

@thierryskoda
Copy link
Copy Markdown
Contributor

@thierryskoda thierryskoda commented Jun 7, 2025

I refactored the logout function within features/authentication/use-logout.ts to execute cleanup operations in the background, without waiting for their completion.

Here's what I changed:

  • I removed the await keyword from all asynchronous cleanup operations, including calls to unsubscribeFromAllConversationsNotifications, stopStreaming, unlinkIdentityFromDeviceMutation, unregisterPushNotifications, unregisterBackgroundSyncTask, logoutXmtpClient, and clearTurnkeySessions. This allows these tasks to run in parallel without blocking the main thread.
  • I removed the customPromiseAllSettled utility, as individual promises are now fired off independently.
  • I introduced the void operator before each background promise (e.g., void Promise.all(...), void stopStreaming(...)). This explicitly signals that the promise's return value is intentionally not awaited or handled directly, preventing linting warnings about unhandled promises while clearly stating the "fire-and-forget" intent.
  • I implemented individual .catch() blocks for each background operation. This ensures that any errors occurring during these non-blocking tasks are still captured and logged via captureError, maintaining error visibility without blocking the logout flow.
  • I moved the clearImageCache call from the finally block into the try block and made it a background operation using void.
  • I adjusted the order of operations to prioritize immediate user feedback. State updates like setting the authentication status to "signedOut" (useAuthenticationStore.getState().actions.setStatus("signedOut")) and resetting various stores (useMultiInboxStore, useNotificationsStore, clearReacyQueryQueriesAndCache) now occur immediately after the background tasks are initiated, providing a faster perceived logout experience.
  • I added a setTimeout with a 500ms delay before hiding the full-screen overlay and setting isLoggingOut to false. This ensures a smoother visual transition for the user, preventing an abrupt disappearance of the loading state.

The outcome is a significantly faster and more responsive logout process, as the user is immediately signed out while resource cleanup continues efficiently in the background. Errors from background tasks are still logged, ensuring operational visibility.

Summary by CodeRabbit

  • Refactor
    • Improved the logout process for better performance and reliability, ensuring all cleanup tasks run in the background with enhanced error handling.
    • Added a short delay after logout to provide a smoother transition when hiding the full-screen overlay.

@thierryskoda thierryskoda requested a review from a team as a code owner June 7, 2025 13:40
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jun 7, 2025

Walkthrough

The logout function in the authentication module was refactored to execute multiple asynchronous cleanup operations concurrently in the background, each with individual error handling. The main logout steps now proceed without waiting for these background tasks. A 500ms delay was introduced before updating the UI to ensure a smoother transition.

Changes

File(s) Change Summary
features/authentication/use-logout.ts Refactored logout to run cleanup tasks concurrently in background with per-task error handling; removed custom promise-all-settled utility; added 500ms UI delay.

Poem

A logout now swift as a hare on the run,
Cleanup tasks scatter—each handled, none shunned.
Errors are caught, but the user moves on,
With a pause for smoothness before logout is done.
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@macroscopeapp
Copy link
Copy Markdown

macroscopeapp bot commented Jun 7, 2025

Execute logout tasks in background by refactoring the logout function in features/authentication/use-logout.ts to run cleanup operations without awaiting completion

The logout function in features/authentication/use-logout.ts changes from a blocking approach that awaits all cleanup operations to a non-blocking approach that executes cleanup tasks in the background. The function removes customPromiseAllSettled usage and instead uses the void operator to fire off operations without awaiting them, adds individual error handling with .catch() blocks for each operation, introduces a 500ms timeout before hiding the overlay in the success path, and immediately proceeds with setting auth status and clearing stores rather than waiting for cleanup completion.

📍Where to Start

Start with the logout function in features/authentication/use-logout.ts.


Macroscope summarized ce301fc.

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: 0

🧹 Nitpick comments (2)
features/authentication/use-logout.ts (2)

64-93: Consider using consistent error handling pattern.

While functionally correct, this IIFE pattern with internal try-catch differs from the .catch() chaining used in other background operations. Consider refactoring for consistency.

-          // Unlink identities from device
-          void (async () => {
-            try {
-              const currentUser = getCurrentUserQueryData()
-              if (!currentUser) {
-                return
-              }
-              const currentDevice = await ensureUserDeviceQueryData({
-                userId: currentUser.id,
-              })
-              const currentUserIdentities = await ensureUserIdentitiesQueryData({
-                userId: currentUser.id,
-              })
-              await Promise.all(
-                currentUserIdentities.map((identity) =>
-                  unlinkIdentityFromDeviceMutation({
-                    identityId: identity.id,
-                    deviceId: currentDevice.id,
-                  }),
-                ),
-              )
-            } catch (error) {
-              captureError(
-                new GenericError({
-                  error,
-                  additionalMessage: "Error unlinking identities from device",
-                }),
-              )
-            }
-          })()
+          // Unlink identities from device
+          void (async () => {
+            const currentUser = getCurrentUserQueryData()
+            if (!currentUser) {
+              return
+            }
+            const currentDevice = await ensureUserDeviceQueryData({
+              userId: currentUser.id,
+            })
+            const currentUserIdentities = await ensureUserIdentitiesQueryData({
+              userId: currentUser.id,
+            })
+            await Promise.all(
+              currentUserIdentities.map((identity) =>
+                unlinkIdentityFromDeviceMutation({
+                  identityId: identity.id,
+                  deviceId: currentDevice.id,
+                }),
+              ),
+            )
+          })().catch((error: unknown) => {
+            captureError(
+              new GenericError({
+                error,
+                additionalMessage: "Error unlinking identities from device",
+              }),
+            )
+          })

157-161: Consider making the transition delay configurable.

The 500ms delay works well for smooth transitions, but consider making it configurable or adaptive based on device performance for optimal UX across different devices.

+        // Configurable delay for smooth transition
+        const LOGOUT_TRANSITION_DELAY_MS = 500
+        
         // Give a small delay before hiding the overlay to ensure smooth transition
         setTimeout(() => {
           useAppStore.getState().actions.setIsShowingFullScreenOverlay(false)
           useAppStore.getState().actions.setIsLoggingOut(false)
-        }, 500)
+        }, LOGOUT_TRANSITION_DELAY_MS)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f794be and ce301fc.

📒 Files selected for processing (1)
  • features/authentication/use-logout.ts (1 hunks)
🔇 Additional comments (6)
features/authentication/use-logout.ts (6)

37-52: LGTM! Good use of fire-and-forget pattern.

The refactoring to execute unsubscribe operations in the background is well-implemented with proper error handling.


54-62: Pattern consistency maintained.


95-107: Consistent implementation.


149-155: Excellent UX optimization!

Setting auth status and clearing stores immediately provides instant user feedback while background cleanup continues. This achieves the goal of a faster perceived logout experience.


163-169: Good defensive error handling!

Adding UI state reset in the catch block ensures the app doesn't get stuck in a loading state if logout fails.


32-170: Verify behavior when user logs in quickly after logout.

With background tasks continuing after logout, there's a potential for race conditions if a user logs out and immediately logs back in. The background cleanup tasks from the previous session might interfere with the new session.

Consider testing the following scenario:

  1. User initiates logout
  2. User immediately logs back in (within ~1-2 seconds)
  3. Verify that background tasks from the previous session don't interfere with the new session

This is particularly important for operations like:

  • Push notification registration/unregistration
  • XMTP client logout/login
  • Device identity linking/unlinking

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