Project

General

Profile

Actions

Bug #31466

open

Improvement #31248: New Theme based Nextjs application dev analysis

Improvement #31319: Basic Next.js Setup and Architecture Implementation

When multiple tabs or concurrent requests attempted to refresh an expired token simultaneously

Added by Sachin Suresh 4 months ago. Updated 4 months ago.

Status:
Fixed not Tested
Priority:
Normal
Assignee:
Target version:
-
Start date:
12/19/2025
Due date:
12/19/2025 (about 4 months late)
% Done:

100%

Estimated time:
Spent time:
remarks:
DB Changes:
Keys & Permissions:
Areas Affected:
Files Changed:

Description

Both requests would initiate a refresh call to the Identity Provider.
The first one would succeed.
The second one would fail (because the refresh token was rotated/invalidated by the first call).
This would trigger "Guest Recovery" or logout, breaking the session for the second tab.

Actions #1

Updated by Sachin Suresh 4 months ago

  • Status changed from Assigned to In Progress
Actions #2

Updated by Sachin Suresh 4 months ago

  • Status changed from In Progress to Fixed not Tested
  • % Done changed from 0 to 100

In-Memory Promise Deduplication
We handle this synchronization at the Server Action layer (`auth-actions.ts`), creating a "Smart Server, Dumb Client" architecture.
1. Client Role: The client simply polls `getSession` every 10s. It has no complex synchronization logic.
2. Server Role:
- Maintains a `refreshPromises` map in memory.
- Leader Election: The first request creates a promise and calls the API.
- Followers: Subsequent requests for the same session ID join the existing promise and await the result.
- Result: Using `await refreshPromises[sessionId]`, only one network call is made to the Auth Provider, regardless of how many tabs triggered the refresh.

known issues

Scaling Limitation: This implementation relies on process memory (RAM). In a distributed environment (Serverless/Kubernetes), requests might hit different instances which cannot share this lock. For distributed deployments, this must be replaced with a distributed lock (e.g., Redis `SETNX`).

Actions

Also available in: Atom PDF