Skip to content

Commit

Permalink
Fix: Issue of synchronizing namespaced local memory caches (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
gkachru authored Oct 1, 2024
1 parent 32943e2 commit f077d30
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 11 deletions.
25 changes: 14 additions & 11 deletions packages/bentocache/src/cache/stack/cache_stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export class CacheStack {
l1?: LocalCache
l2?: RemoteCache
bus?: Bus
#busDriver?: BusDriver
#busOptions?: BusOptions
defaultOptions: CacheEntryOptions
logger: Logger

Expand All @@ -46,22 +48,23 @@ export class CacheStack {
if (bus) return bus
if (!busDriver || !this.l1) return

const opts = lodash.merge({ retryQueue: { enabled: true, maxSize: undefined } }, busOptions)
const newBus = new Bus(busDriver, this.l1, this.logger, this.emitter, opts)
this.#busDriver = busDriver
this.#busOptions = lodash.merge(
{ retryQueue: { enabled: true, maxSize: undefined } },
busOptions,
)
const newBus = new Bus(this.#busDriver, this.l1, this.logger, this.emitter, this.#busOptions)

return newBus
}

namespace(namespace: string) {
return new CacheStack(
this.name,
this.options,
{
l1Driver: this.l1?.namespace(namespace),
l2Driver: this.l2?.namespace(namespace),
},
this.bus,
)
return new CacheStack(this.name, this.options, {
l1Driver: this.l1?.namespace(namespace),
l2Driver: this.l2?.namespace(namespace),
busDriver: this.#busDriver,
busOptions: this.#busOptions,
})
}

emit(event: CacheEvent) {
Expand Down
56 changes: 56 additions & 0 deletions packages/bentocache/tests/bus/bus.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,62 @@ test.group('Bus synchronization', () => {
assert.isUndefined(await cache3.get(key))
}).disableTimeout()

test('synchronize multiple cache with a namespace', async ({ assert }) => {
const key = 'foo'

const [cache1] = new CacheFactory().withL1L2Config().create()
const [cache2] = new CacheFactory().withL1L2Config().create()
const [cache3] = new CacheFactory().withL1L2Config().create()

await cache1.namespace('users').set(key, 24)
await setTimeout(100)

assert.equal(await cache1.namespace('users').get(key), 24)
assert.equal(await cache2.namespace('users').get(key), 24)
assert.equal(await cache3.namespace('users').get(key), 24)

await cache1.namespace('users').delete(key)

await setTimeout(100)

assert.isUndefined(await cache1.namespace('users').get(key))
assert.isUndefined(await cache2.namespace('users').get(key))
assert.isUndefined(await cache3.namespace('users').get(key))
}).disableTimeout()

test('synchronize multiple cache with multiple namespaces', async ({ assert }) => {
const key = 'bar'

const [cache1] = new CacheFactory().withL1L2Config().create()
const [cache2] = new CacheFactory().withL1L2Config().create()
const [cache3] = new CacheFactory().withL1L2Config().create()

const cache1NSUsersMe = cache1.namespace('users').namespace('me')
const cache2NSUsersMe = cache2.namespace('users').namespace('me')
const cache3NSAdmin = cache3.namespace('admin')

await cache1NSUsersMe.set(key, 24)
await cache3NSAdmin.set(key, 42)
await setTimeout(100)

assert.equal(await cache1NSUsersMe.get(key), 24)
assert.equal(await cache2NSUsersMe.get(key), 24)
assert.equal(await cache3NSAdmin.get(key), 42)

await cache1NSUsersMe.clear()

await setTimeout(100)

assert.isUndefined(await cache1NSUsersMe.get(key))
assert.isUndefined(await cache2.namespace('users').namespace('me').get(key))
assert.equal(await cache3NSAdmin.get(key), 42)

await cache2.namespace('admin').clear()
await setTimeout(100)

assert.isUndefined(await cache3NSAdmin.get(key))
}).disableTimeout()

test('retry queue processing', async ({ assert }) => {
const bus1 = new ChaosBus(new MemoryTransport())
const bus2 = new ChaosBus(new MemoryTransport())
Expand Down

0 comments on commit f077d30

Please sign in to comment.