Updating writethrough cache a bit to make sure it implements the PouchDB API properly.

This commit is contained in:
mike12345567 2022-06-24 13:34:00 +01:00
parent e3f25795e8
commit eeca1cb3ba
3 changed files with 54 additions and 25 deletions

View File

@ -3,5 +3,6 @@ const generic = require("./src/cache/generic")
module.exports = {
user: require("./src/cache/user"),
app: require("./src/cache/appMetadata"),
writethrough: require("./src/cache/writethrough"),
...generic,
}

View File

@ -9,30 +9,30 @@ tk.freeze(START_DATE)
const DELAY = 5000
const db = dangerousGetDB("test")
const writethrough = new Writethrough(db)
const writethrough = new Writethrough(db, DELAY)
describe("writethrough", () => {
describe("put", () => {
let first
it("should be able to store, will go to DB", async () => {
const response = await writethrough.put({ _id: "test", value: 1 }, DELAY)
const output = await db.get(response._id)
const response = await writethrough.put({ _id: "test", value: 1 })
const output = await db.get(response.id)
first = output
expect(output.value).toBe(1)
})
it("second put shouldn't update DB", async () => {
const response = await writethrough.put({ ...first, value: 2 }, DELAY)
const output = await db.get(response._id)
const response = await writethrough.put({ ...first, value: 2 })
const output = await db.get(response.id)
expect(first._rev).toBe(output._rev)
expect(output.value).toBe(1)
})
it("should put it again after delay period", async () => {
tk.freeze(START_DATE + DELAY + 1)
const response = await writethrough.put({ ...first, value: 3 }, DELAY)
const output = await db.get(response._id)
expect(response._rev).not.toBe(first._rev)
const response = await writethrough.put({ ...first, value: 3 })
const output = await db.get(response.id)
expect(response.rev).not.toBe(first._rev)
expect(output.value).toBe(3)
})
})

View File

@ -5,7 +5,7 @@ const DEFAULT_WRITE_RATE_MS = 10000
let CACHE: BaseCache | null = null
interface CacheItem {
value: any
doc: any
lastWrite: number
}
@ -17,57 +17,85 @@ async function getCache() {
return CACHE
}
function makeCacheItem(value: any, lastWrite: number | null = null): CacheItem {
return { value, lastWrite: lastWrite || Date.now() }
function makeCacheItem(doc: any, lastWrite: number | null = null): CacheItem {
return { doc, lastWrite: lastWrite || Date.now() }
}
export async function put(
db: PouchDB.Database,
value: any,
doc: any,
writeRateMs: number = DEFAULT_WRITE_RATE_MS
) {
const cache = await getCache()
const key = value._id
const key = doc._id
let cacheItem: CacheItem | undefined = await cache.get(key)
const updateDb = !cacheItem || cacheItem.lastWrite < Date.now() - writeRateMs
let output = value
let output = doc
if (updateDb) {
// value should contain the _id and _rev
const response = await db.put(value)
// doc should contain the _id and _rev
const response = await db.put(doc)
output = {
...value,
...doc,
_id: response.id,
_rev: response.rev,
}
}
// if we are updating the DB then need to set the lastWrite to now
cacheItem = makeCacheItem(value, updateDb ? null : cacheItem?.lastWrite)
cacheItem = makeCacheItem(output, updateDb ? null : cacheItem?.lastWrite)
await cache.store(key, cacheItem)
return output
return { ok: true, id: output._id, rev: output._rev }
}
export async function get(db: PouchDB.Database, id: string): Promise<any> {
const cache = await getCache()
let cacheItem: CacheItem = await cache.get(id)
if (!cacheItem) {
const value = await db.get(id)
cacheItem = makeCacheItem(value)
const doc = await db.get(id)
cacheItem = makeCacheItem(doc)
await cache.store(id, cacheItem)
}
return cacheItem.value
return cacheItem.doc
}
export async function remove(
db: PouchDB.Database,
docOrId: any,
rev?: any
): Promise<void> {
const cache = await getCache()
if (!docOrId) {
throw new Error("No ID/Rev provided.")
}
const id = typeof docOrId === "string" ? docOrId : docOrId._id
rev = typeof docOrId === "string" ? rev : docOrId._rev
try {
await cache.delete(id)
} finally {
await db.remove(id, rev)
}
}
export class Writethrough {
db: PouchDB.Database
constructor(db: PouchDB.Database) {
writeRateMs: number
constructor(
db: PouchDB.Database,
writeRateMs: number = DEFAULT_WRITE_RATE_MS
) {
this.db = db
this.writeRateMs = writeRateMs
}
async put(value: any, writeRateMs: number = DEFAULT_WRITE_RATE_MS) {
return put(this.db, value, writeRateMs)
async put(doc: any) {
return put(this.db, doc, this.writeRateMs)
}
async get(id: string) {
return get(this.db, id)
}
async remove(docOrId: any, rev?: any) {
return remove(this.db, docOrId, rev)
}
}