Adding case to handle multi-DB setups, to confirm store same doc ID to different databases and they run in different cache keys.

This commit is contained in:
mike12345567 2022-06-24 14:28:45 +01:00
parent eeca1cb3ba
commit c62b6da703
2 changed files with 36 additions and 12 deletions

View File

@ -9,7 +9,8 @@ tk.freeze(START_DATE)
const DELAY = 5000 const DELAY = 5000
const db = dangerousGetDB("test") const db = dangerousGetDB("test")
const writethrough = new Writethrough(db, DELAY) const db2 = dangerousGetDB("test2")
const writethrough = new Writethrough(db, DELAY), writethrough2 = new Writethrough(db2, DELAY)
describe("writethrough", () => { describe("writethrough", () => {
describe("put", () => { describe("put", () => {
@ -43,5 +44,16 @@ describe("writethrough", () => {
expect(response.value).toBe(3) expect(response.value).toBe(3)
}) })
}) })
describe("same doc, different databases (tenancy)", () => {
it("should be able to two different databases", async () => {
const resp1 = await writethrough.put({ _id: "db1", value: "first" })
const resp2 = await writethrough2.put({ _id: "db1", value: "second" })
expect(resp1.rev).toBeDefined()
expect(resp2.rev).toBeDefined()
expect((await db.get("db1")).value).toBe("first")
expect((await db2.get("db1")).value).toBe("second")
})
})
}) })

View File

@ -17,6 +17,10 @@ async function getCache() {
return CACHE return CACHE
} }
function makeCacheKey(db: PouchDB.Database, key: string) {
return db.name + key
}
function makeCacheItem(doc: any, lastWrite: number | null = null): CacheItem { function makeCacheItem(doc: any, lastWrite: number | null = null): CacheItem {
return { doc, lastWrite: lastWrite || Date.now() } return { doc, lastWrite: lastWrite || Date.now() }
} }
@ -28,31 +32,39 @@ export async function put(
) { ) {
const cache = await getCache() const cache = await getCache()
const key = doc._id const key = doc._id
let cacheItem: CacheItem | undefined = await cache.get(key) let cacheItem: CacheItem | undefined = await cache.get(makeCacheKey(db, key))
const updateDb = !cacheItem || cacheItem.lastWrite < Date.now() - writeRateMs const updateDb = !cacheItem || cacheItem.lastWrite < Date.now() - writeRateMs
let output = doc let output = doc
if (updateDb) { if (updateDb) {
// doc should contain the _id and _rev try {
const response = await db.put(doc) // doc should contain the _id and _rev
output = { const response = await db.put(doc)
...doc, output = {
_id: response.id, ...doc,
_rev: response.rev, _id: response.id,
_rev: response.rev,
}
} catch (err: any) {
// ignore 409s, some other high speed write has hit it first, just move straight to caching
if (err.status !== 409) {
throw err
}
} }
} }
// if we are updating the DB then need to set the lastWrite to now // if we are updating the DB then need to set the lastWrite to now
cacheItem = makeCacheItem(output, updateDb ? null : cacheItem?.lastWrite) cacheItem = makeCacheItem(output, updateDb ? null : cacheItem?.lastWrite)
await cache.store(key, cacheItem) await cache.store(makeCacheKey(db, key), cacheItem)
return { ok: true, id: output._id, rev: output._rev } return { ok: true, id: output._id, rev: output._rev }
} }
export async function get(db: PouchDB.Database, id: string): Promise<any> { export async function get(db: PouchDB.Database, id: string): Promise<any> {
const cache = await getCache() const cache = await getCache()
let cacheItem: CacheItem = await cache.get(id) const cacheKey = makeCacheKey(db, id)
let cacheItem: CacheItem = await cache.get(cacheKey)
if (!cacheItem) { if (!cacheItem) {
const doc = await db.get(id) const doc = await db.get(id)
cacheItem = makeCacheItem(doc) cacheItem = makeCacheItem(doc)
await cache.store(id, cacheItem) await cache.store(cacheKey, cacheItem)
} }
return cacheItem.doc return cacheItem.doc
} }
@ -69,7 +81,7 @@ export async function remove(
const id = typeof docOrId === "string" ? docOrId : docOrId._id const id = typeof docOrId === "string" ? docOrId : docOrId._id
rev = typeof docOrId === "string" ? rev : docOrId._rev rev = typeof docOrId === "string" ? rev : docOrId._rev
try { try {
await cache.delete(id) await cache.delete(makeCacheKey(db, id))
} finally { } finally {
await db.remove(id, rev) await db.remove(id, rev)
} }