email: real-time IMAP IDLE watchers (push on new mail); cron kept as backstop

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 17:22:46 +00:00
co-authored by Claude Opus 4.8
parent 2bef99866f
commit 5a0b9ce70f
3 changed files with 174 additions and 1 deletions
+13 -1
View File
@@ -271,7 +271,19 @@ type ResyncParams = {
userId: number;
};
export async function performResync({ accountId, userEmail, userId }: ResyncParams): Promise<ResyncResult> {
// Coalesce concurrent resyncs of the same account within this process (IDLE + cron + manual can all
// fire) — a caller arriving mid-resync just awaits the one already running.
const resyncInFlight = new Map<number, Promise<ResyncResult>>();
export function performResync(params: ResyncParams): Promise<ResyncResult> {
const running = resyncInFlight.get(params.accountId);
if (running) return running;
const p = doResync(params).finally(() => resyncInFlight.delete(params.accountId));
resyncInFlight.set(params.accountId, p);
return p;
}
async function doResync({ accountId, userEmail, userId }: ResyncParams): Promise<ResyncResult> {
const account = await getEmailAccount(accountId);
if (!account || account.userId !== userId) throw new Error('Account not found');