@bobfrankston/rmfmail 1.2.2 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/packages/mailx-imap/index.d.ts.map +1 -1
- package/packages/mailx-imap/index.js +10 -8
- package/packages/mailx-imap/index.js.map +1 -1
- package/packages/mailx-imap/index.ts +10 -8
- package/packages/mailx-imap/package-lock.json +2 -2
- package/packages/mailx-imap/package.json +1 -1
- package/packages/mailx-service/index.d.ts +11 -1
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +41 -7
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +35 -9
- package/packages/mailx-store/package.json +1 -1
|
@@ -291,19 +291,45 @@ export class MailxService implements MailxApi {
|
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
+
/** In-flight read coalescing. A slow daemon makes the UI re-fire the same
|
|
295
|
+
* read (scroll loadMore retries, poll loops, re-render storms): the log
|
|
296
|
+
* showed the IDENTICAL getUnifiedInbox queued dozens of times and all
|
|
297
|
+
* draining at once after a 78s stall. Keyed by method+args, a duplicate
|
|
298
|
+
* request that arrives while one is already running shares that single
|
|
299
|
+
* promise instead of enqueuing another worker job. Same args ⇒ same
|
|
300
|
+
* result, so this is always safe; different args (other pages) key
|
|
301
|
+
* separately. This caps the worker queue at one job per distinct read. */
|
|
302
|
+
private inflightReads = new Map<string, Promise<any>>();
|
|
303
|
+
|
|
294
304
|
/** Route a read through the worker bus if it's up, else run it in-process.
|
|
295
305
|
* A worker-side error (or a dead worker) transparently falls back so a
|
|
296
|
-
* read never fails just because the isolation layer hiccuped.
|
|
306
|
+
* read never fails just because the isolation layer hiccuped. Identical
|
|
307
|
+
* concurrent reads are coalesced (see inflightReads). */
|
|
297
308
|
private async read<R>(method: string, args: any, local: () => R): Promise<R> {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
309
|
+
let key: string;
|
|
310
|
+
try { key = method + ":" + JSON.stringify(args); }
|
|
311
|
+
catch { key = ""; } // unserializable args → don't coalesce
|
|
312
|
+
if (key) {
|
|
313
|
+
const existing = this.inflightReads.get(key);
|
|
314
|
+
if (existing) return existing as Promise<R>;
|
|
315
|
+
}
|
|
316
|
+
const run = (async (): Promise<R> => {
|
|
317
|
+
const w = this.dbWorker;
|
|
318
|
+
if (w) {
|
|
319
|
+
try {
|
|
320
|
+
return await w.bus.request<any, R>(method, args);
|
|
321
|
+
} catch (e: any) {
|
|
322
|
+
console.error(` [read-worker] ${method} failed (${e?.message || e}); in-process fallback`);
|
|
323
|
+
}
|
|
304
324
|
}
|
|
305
|
-
|
|
306
|
-
|
|
325
|
+
return local();
|
|
326
|
+
})();
|
|
327
|
+
if (key) {
|
|
328
|
+
this.inflightReads.set(key, run);
|
|
329
|
+
try { return await run; }
|
|
330
|
+
finally { this.inflightReads.delete(key); }
|
|
331
|
+
}
|
|
332
|
+
return run;
|
|
307
333
|
}
|
|
308
334
|
/** Transitional getter — direct DB access from MailxService for the
|
|
309
335
|
* ~50 callsites that haven't yet migrated to Store methods. Future:
|