From 8d775fbf2153f57699f4903f0e5d9077bfa7657b Mon Sep 17 00:00:00 2001 From: Aleksandr Bunin Date: Wed, 18 Sep 2024 11:05:44 +0300 Subject: [PATCH 1/5] made adTTL lazy --- CHANGELOG.md | 6 +++ .../decorators/helpers/add-emitter/index.ts | 8 ++- src/core/cache/decorators/ttl/CHANGELOG.md | 6 +++ src/core/cache/decorators/ttl/index.ts | 52 +++++++++++++++---- 4 files changed, 56 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e9112331..f80b37231 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,12 @@ Changelog _Note: Gaps between patch versions are faulty, broken or test releases._ +## v4.0.0-alpha.46 (2024-09-18) + +#### :house: Internal + +* Made the `addTTL` functionality lazy `core/cache/docorators/ttl` + ## v4.0.0-alpha.45 (2024-09-09) #### :bug: Bug Fix diff --git a/src/core/cache/decorators/helpers/add-emitter/index.ts b/src/core/cache/decorators/helpers/add-emitter/index.ts index 6269653cf..d9d33a6ca 100644 --- a/src/core/cache/decorators/helpers/add-emitter/index.ts +++ b/src/core/cache/decorators/helpers/add-emitter/index.ts @@ -137,14 +137,12 @@ const addEmitter: AddEmitter = , V = unknown, K extends st clear: originalClear.bind(cacheWithEmitter), subscribe: ((method, obj, cb): void => { - emitter.on(method, handler); - - function handler(cacheWithEmitter: object, e: MutationEvent) { + emitter.on(method, (cacheWithEmitter: object, e: MutationEvent) => { // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions - if (cacheWithEmitter === obj || {}.isPrototypeOf.call(cacheWithEmitter, obj)) { + if (cacheWithEmitter === obj || cacheWithEmitter.isPrototypeOf(obj)) { cb(e); } - } + }); }) }; }; diff --git a/src/core/cache/decorators/ttl/CHANGELOG.md b/src/core/cache/decorators/ttl/CHANGELOG.md index 97a9316e2..fd293218e 100644 --- a/src/core/cache/decorators/ttl/CHANGELOG.md +++ b/src/core/cache/decorators/ttl/CHANGELOG.md @@ -9,6 +9,12 @@ Changelog > - :house: [Internal] > - :nail_care: [Polish] +## v4.0.0-alpha.46 (2024-09-18) + +#### :house: Internal + +* Made `addTTL` functionality lazy + ## v3.47.0 (2021-05-17) #### :bug: Bug Fix diff --git a/src/core/cache/decorators/ttl/index.ts b/src/core/cache/decorators/ttl/index.ts index 123d1c871..a29e387ef 100644 --- a/src/core/cache/decorators/ttl/index.ts +++ b/src/core/cache/decorators/ttl/index.ts @@ -54,8 +54,31 @@ export default function addTTL< } = addEmitter, V, K>(>cache); const - cacheWithTTL: TTLCache = Object.create(cache), - ttlTimers = new Map(); + ttlStore = new Map(), + dateStore = new Map(); + + const + cacheWithTTL: TTLCache = Object.create(cache); + + cacheWithTTL.get = (key: K) => { + const + dateSet = dateStore.get(key), + ttl = ttlStore.get(key); + + if (dateSet != null && ttl != null) { + const + expired = Date.now() - dateSet > ttl; + + if (expired) { + cacheWithTTL.remove(key); + return; + } + } + + return cache.get(key); + }; + + cacheWithTTL.has = (key: K) => cacheWithTTL.get(key) !== undefined; cacheWithTTL.set = (key: K, value: V, opts?: TTLDecoratorOptions & Parameters[2]) => { updateTTL(key, opts?.ttl); @@ -68,9 +91,10 @@ export default function addTTL< }; cacheWithTTL.removeTTLFrom = (key: K) => { - if (ttlTimers.has(key)) { - clearTimeout(ttlTimers.get(key)); - ttlTimers.delete(key); + if (ttlStore.has(key) || dateStore.has(key)) { + ttlStore.delete(key); + dateStore.delete(key); + return true; } @@ -81,9 +105,13 @@ export default function addTTL< const removed = originalClear(filter); - removed.forEach((_, key) => { - cacheWithTTL.removeTTLFrom(key); - }); + if (filter == null) { + ttlStore.clear(); + dateStore.clear(); + + } else { + removed.forEach((_, key) => cacheWithTTL.removeTTLFrom(key)); + } return removed; }; @@ -101,9 +129,11 @@ export default function addTTL< return cacheWithTTL; function updateTTL(key: K, optionTTL?: number): void { - if (optionTTL != null || ttl != null) { - const time = optionTTL ?? ttl; - ttlTimers.set(key, setTimeout(() => cacheWithTTL.remove(key), time)); + const time = optionTTL ?? ttl; + + if (time != null) { + ttlStore.set(key, time); + dateStore.set(key, Date.now()); } else { cacheWithTTL.removeTTLFrom(key); From 7c4deec5394a93f50543fe230c9f5d723dffd270 Mon Sep 17 00:00:00 2001 From: Aleksandr Bunin Date: Wed, 18 Sep 2024 11:08:15 +0300 Subject: [PATCH 2/5] chore --- CHANGELOG.md | 2 +- src/core/cache/decorators/ttl/CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f80b37231..a6007e06d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ _Note: Gaps between patch versions are faulty, broken or test releases._ #### :house: Internal -* Made the `addTTL` functionality lazy `core/cache/docorators/ttl` +* Changed the logic of the `addTTL` decorator to be lazy `core/cache/docorators/ttl` ## v4.0.0-alpha.45 (2024-09-09) diff --git a/src/core/cache/decorators/ttl/CHANGELOG.md b/src/core/cache/decorators/ttl/CHANGELOG.md index fd293218e..6dc4cb01f 100644 --- a/src/core/cache/decorators/ttl/CHANGELOG.md +++ b/src/core/cache/decorators/ttl/CHANGELOG.md @@ -13,7 +13,7 @@ Changelog #### :house: Internal -* Made `addTTL` functionality lazy +* Changed the logic of the `addTTL` decorator to be lazy ## v3.47.0 (2021-05-17) From a084477c1601c3409d36318d1e93adea3be68bc8 Mon Sep 17 00:00:00 2001 From: Aleksandr Bunin Date: Wed, 18 Sep 2024 21:22:33 +0300 Subject: [PATCH 3/5] change test --- src/core/cache/decorators/spec.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/cache/decorators/spec.js b/src/core/cache/decorators/spec.js index b0d6f1149..f6ace8068 100644 --- a/src/core/cache/decorators/spec.js +++ b/src/core/cache/decorators/spec.js @@ -17,8 +17,6 @@ import { INDEX_STORAGE_NAME } from 'core/cache/decorators/persistent/engines/con describe('core/cache/decorators', () => { it('complex test', async () => { - jest.spyOn(Date, 'now').mockReturnValue(0); - const opts = { loadFromStorage: 'onInit' }; @@ -44,6 +42,11 @@ describe('core/cache/decorators', () => { }); await new Promise((r) => setTimeout(r, 50)); + + expect(await persistentCache.get('bar')).toBe(undefined); + + await new Promise((r) => setTimeout(r, 0)); + expect(await asyncLocal.get(INDEX_STORAGE_NAME)).toEqual({ baz: Number.MAX_SAFE_INTEGER }); From 3cc5557d00c92cbb6c2520e652b02a8acdb1d9a5 Mon Sep 17 00:00:00 2001 From: Aleksandr Bunin Date: Wed, 18 Sep 2024 23:47:38 +0300 Subject: [PATCH 4/5] chore --- src/core/cache/decorators/helpers/add-emitter/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/cache/decorators/helpers/add-emitter/index.ts b/src/core/cache/decorators/helpers/add-emitter/index.ts index d9d33a6ca..f62465c07 100644 --- a/src/core/cache/decorators/helpers/add-emitter/index.ts +++ b/src/core/cache/decorators/helpers/add-emitter/index.ts @@ -139,7 +139,7 @@ const addEmitter: AddEmitter = , V = unknown, K extends st subscribe: ((method, obj, cb): void => { emitter.on(method, (cacheWithEmitter: object, e: MutationEvent) => { // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions - if (cacheWithEmitter === obj || cacheWithEmitter.isPrototypeOf(obj)) { + if (cacheWithEmitter === obj || {}.isPrototypeOf.call(cacheWithEmitter, obj)) { cb(e); } }); From bff1aa499160dce6ae530cba6bb3e86bbd49afb9 Mon Sep 17 00:00:00 2001 From: Aleksandr Bunin Date: Fri, 20 Sep 2024 15:58:35 +0300 Subject: [PATCH 5/5] refactor: make 1 store --- src/core/cache/decorators/ttl/index.ts | 30 +++++++++----------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/core/cache/decorators/ttl/index.ts b/src/core/cache/decorators/ttl/index.ts index a29e387ef..9f1b2a9a8 100644 --- a/src/core/cache/decorators/ttl/index.ts +++ b/src/core/cache/decorators/ttl/index.ts @@ -54,20 +54,18 @@ export default function addTTL< } = addEmitter, V, K>(>cache); const - ttlStore = new Map(), - dateStore = new Map(); + store = new Map(); const cacheWithTTL: TTLCache = Object.create(cache); cacheWithTTL.get = (key: K) => { const - dateSet = dateStore.get(key), - ttl = ttlStore.get(key); + info = store.get(key); - if (dateSet != null && ttl != null) { + if (info != null) { const - expired = Date.now() - dateSet > ttl; + expired = Date.now() - info.date > info.ttl; if (expired) { cacheWithTTL.remove(key); @@ -90,24 +88,14 @@ export default function addTTL< return originalRemove(key); }; - cacheWithTTL.removeTTLFrom = (key: K) => { - if (ttlStore.has(key) || dateStore.has(key)) { - ttlStore.delete(key); - dateStore.delete(key); - - return true; - } - - return false; - }; + cacheWithTTL.removeTTLFrom = (key: K) => store.delete(key); cacheWithTTL.clear = (filter?: ClearFilter) => { const removed = originalClear(filter); if (filter == null) { - ttlStore.clear(); - dateStore.clear(); + store.clear(); } else { removed.forEach((_, key) => cacheWithTTL.removeTTLFrom(key)); @@ -132,8 +120,10 @@ export default function addTTL< const time = optionTTL ?? ttl; if (time != null) { - ttlStore.set(key, time); - dateStore.set(key, Date.now()); + store.set(key, { + ttl: time, + date: Date.now() + }); } else { cacheWithTTL.removeTTLFrom(key);