perf(auth): restore the other logins a few at a time

After the login on screen, the rest were restored one after the other, so
the last of them - and with it a complete unified inbox - waited on every
other login's round trips: with ten logins it arrived about five seconds
after the first. Restore them four at a time. Each restore already handles
its own failures, so a slow or broken login holds up only its own slot.
This commit is contained in:
lucamzanon
2026-09-30 19:04:49 +02:00
parent 612dcc81ee
commit 3ec9cd7201
+17 -3
View File
@@ -45,6 +45,9 @@ import {
} from '@/lib/auth/lite-tokens';
import { clearLiteOAuthFlow, readLiteOAuthFlow } from '@/lib/auth/lite-oauth';
/** Logins restored at once after the one on screen: enough to overlap round trips, few enough not to crowd the server. */
const RESTORE_CONCURRENCY = 4;
interface AuthState {
isAuthenticated: boolean;
isLoading: boolean;
@@ -2486,10 +2489,21 @@ export const useAuthStore = create<AuthState>()(
const otherAccounts = accounts.filter((account) => account.id !== targetId);
if (targetEntry) await restoreAccount(targetEntry);
// A few at a time rather than one after the other: with many logins
// the serial walk left the last of them - and with it a complete
// unified inbox - waiting on every other login's round trips. Each
// restore handles its own failures, so one slow or broken login
// holds up only its own slot.
const restoreRemaining = async () => {
for (const account of otherAccounts) {
await restoreAccount(account);
}
const queue = [...otherAccounts];
const worker = async () => {
for (let next = queue.shift(); next; next = queue.shift()) {
await restoreAccount(next);
}
};
await Promise.allSettled(
Array.from({ length: Math.min(RESTORE_CONCURRENCY, queue.length) }, worker),
);
};
if (clients.has(targetId)) {