From 840a79b885ea44db6b419c98f09fc48101a743ee Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 21 Feb 2026 18:36:04 +0000 Subject: [PATCH] Refactor memory store save logic to use CoalescingWorker - Replaced manual promise management in `src/services/memory/index.js` with a `CoalescingWorker` class. - Extracted `performSave` logic into `performSave` function used by the worker (worker function). - Ensures concurrent calls to `saveMemoryStore` are coalesced into a single pending operation, maintaining data integrity and performance. - Removed global state variables for promise management. Co-authored-by: PR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> --- src/services/memory/index.js | 71 ++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/src/services/memory/index.js b/src/services/memory/index.js index 1c9ec82..d1d01e8 100644 --- a/src/services/memory/index.js +++ b/src/services/memory/index.js @@ -38,9 +38,50 @@ function loadMemoryStore() { return new Map(); } -let currentSavePromise = null; -let pendingSavePromise = null; -let pendingSaveResolve = null; +class CoalescingWorker { + constructor(workerFn) { + this.workerFn = workerFn; + this.currentPromise = null; + this.pendingPromise = null; + this.pendingResolve = null; + this.pendingArg = null; + } + + enqueue(arg) { + this.pendingArg = arg; + + if (this.pendingPromise) { + return this.pendingPromise; + } + + if (this.currentPromise) { + this.pendingPromise = new Promise((resolve) => { + this.pendingResolve = resolve; + }); + return this.pendingPromise; + } + + this.currentPromise = this._execute(arg); + return this.currentPromise; + } + + async _execute(arg) { + try { + await this.workerFn(arg); + } finally { + this.currentPromise = null; + if (this.pendingPromise) { + const resolve = this.pendingResolve; + const nextArg = this.pendingArg; + this.pendingPromise = null; + this.pendingResolve = null; + this.pendingArg = null; + this.currentPromise = this._execute(nextArg).then(resolve); + } + } + } +} + let lastSaveTime = 0; const MIN_SAVE_INTERVAL_MS = 1000; @@ -61,31 +102,13 @@ async function performSave(store) { lastSaveTime = Date.now(); } catch (err) { console.error('Failed to save memory store:', err); - } finally { - currentSavePromise = null; - if (pendingSavePromise) { - const resolve = pendingSaveResolve; - pendingSavePromise = null; - pendingSaveResolve = null; - currentSavePromise = performSave(store).then(() => resolve()); - } } } +const saveWorker = new CoalescingWorker(performSave); + async function saveMemoryStore(store) { - if (pendingSavePromise) { - return pendingSavePromise; - } - - if (currentSavePromise) { - pendingSavePromise = new Promise((resolve) => { - pendingSaveResolve = resolve; - }); - return pendingSavePromise; - } - - currentSavePromise = performSave(store); - return currentSavePromise; + return saveWorker.enqueue(store); } const memoryStore = loadMemoryStore();