Updating writethrough cache a bit to make sure it implements the PouchDB API properly.
This commit is contained in:
parent
e3f25795e8
commit
eeca1cb3ba
|
@ -3,5 +3,6 @@ const generic = require("./src/cache/generic")
|
||||||
module.exports = {
|
module.exports = {
|
||||||
user: require("./src/cache/user"),
|
user: require("./src/cache/user"),
|
||||||
app: require("./src/cache/appMetadata"),
|
app: require("./src/cache/appMetadata"),
|
||||||
|
writethrough: require("./src/cache/writethrough"),
|
||||||
...generic,
|
...generic,
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,30 +9,30 @@ tk.freeze(START_DATE)
|
||||||
const DELAY = 5000
|
const DELAY = 5000
|
||||||
|
|
||||||
const db = dangerousGetDB("test")
|
const db = dangerousGetDB("test")
|
||||||
const writethrough = new Writethrough(db)
|
const writethrough = new Writethrough(db, DELAY)
|
||||||
|
|
||||||
describe("writethrough", () => {
|
describe("writethrough", () => {
|
||||||
describe("put", () => {
|
describe("put", () => {
|
||||||
let first
|
let first
|
||||||
it("should be able to store, will go to DB", async () => {
|
it("should be able to store, will go to DB", async () => {
|
||||||
const response = await writethrough.put({ _id: "test", value: 1 }, DELAY)
|
const response = await writethrough.put({ _id: "test", value: 1 })
|
||||||
const output = await db.get(response._id)
|
const output = await db.get(response.id)
|
||||||
first = output
|
first = output
|
||||||
expect(output.value).toBe(1)
|
expect(output.value).toBe(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("second put shouldn't update DB", async () => {
|
it("second put shouldn't update DB", async () => {
|
||||||
const response = await writethrough.put({ ...first, value: 2 }, DELAY)
|
const response = await writethrough.put({ ...first, value: 2 })
|
||||||
const output = await db.get(response._id)
|
const output = await db.get(response.id)
|
||||||
expect(first._rev).toBe(output._rev)
|
expect(first._rev).toBe(output._rev)
|
||||||
expect(output.value).toBe(1)
|
expect(output.value).toBe(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should put it again after delay period", async () => {
|
it("should put it again after delay period", async () => {
|
||||||
tk.freeze(START_DATE + DELAY + 1)
|
tk.freeze(START_DATE + DELAY + 1)
|
||||||
const response = await writethrough.put({ ...first, value: 3 }, DELAY)
|
const response = await writethrough.put({ ...first, value: 3 })
|
||||||
const output = await db.get(response._id)
|
const output = await db.get(response.id)
|
||||||
expect(response._rev).not.toBe(first._rev)
|
expect(response.rev).not.toBe(first._rev)
|
||||||
expect(output.value).toBe(3)
|
expect(output.value).toBe(3)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -5,7 +5,7 @@ const DEFAULT_WRITE_RATE_MS = 10000
|
||||||
let CACHE: BaseCache | null = null
|
let CACHE: BaseCache | null = null
|
||||||
|
|
||||||
interface CacheItem {
|
interface CacheItem {
|
||||||
value: any
|
doc: any
|
||||||
lastWrite: number
|
lastWrite: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,57 +17,85 @@ async function getCache() {
|
||||||
return CACHE
|
return CACHE
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeCacheItem(value: any, lastWrite: number | null = null): CacheItem {
|
function makeCacheItem(doc: any, lastWrite: number | null = null): CacheItem {
|
||||||
return { value, lastWrite: lastWrite || Date.now() }
|
return { doc, lastWrite: lastWrite || Date.now() }
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function put(
|
export async function put(
|
||||||
db: PouchDB.Database,
|
db: PouchDB.Database,
|
||||||
value: any,
|
doc: any,
|
||||||
writeRateMs: number = DEFAULT_WRITE_RATE_MS
|
writeRateMs: number = DEFAULT_WRITE_RATE_MS
|
||||||
) {
|
) {
|
||||||
const cache = await getCache()
|
const cache = await getCache()
|
||||||
const key = value._id
|
const key = doc._id
|
||||||
let cacheItem: CacheItem | undefined = await cache.get(key)
|
let cacheItem: CacheItem | undefined = await cache.get(key)
|
||||||
const updateDb = !cacheItem || cacheItem.lastWrite < Date.now() - writeRateMs
|
const updateDb = !cacheItem || cacheItem.lastWrite < Date.now() - writeRateMs
|
||||||
let output = value
|
let output = doc
|
||||||
if (updateDb) {
|
if (updateDb) {
|
||||||
// value should contain the _id and _rev
|
// doc should contain the _id and _rev
|
||||||
const response = await db.put(value)
|
const response = await db.put(doc)
|
||||||
output = {
|
output = {
|
||||||
...value,
|
...doc,
|
||||||
_id: response.id,
|
_id: response.id,
|
||||||
_rev: response.rev,
|
_rev: response.rev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 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(value, updateDb ? null : cacheItem?.lastWrite)
|
cacheItem = makeCacheItem(output, updateDb ? null : cacheItem?.lastWrite)
|
||||||
await cache.store(key, cacheItem)
|
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> {
|
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)
|
let cacheItem: CacheItem = await cache.get(id)
|
||||||
if (!cacheItem) {
|
if (!cacheItem) {
|
||||||
const value = await db.get(id)
|
const doc = await db.get(id)
|
||||||
cacheItem = makeCacheItem(value)
|
cacheItem = makeCacheItem(doc)
|
||||||
await cache.store(id, cacheItem)
|
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 {
|
export class Writethrough {
|
||||||
db: PouchDB.Database
|
db: PouchDB.Database
|
||||||
constructor(db: PouchDB.Database) {
|
writeRateMs: number
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
db: PouchDB.Database,
|
||||||
|
writeRateMs: number = DEFAULT_WRITE_RATE_MS
|
||||||
|
) {
|
||||||
this.db = db
|
this.db = db
|
||||||
|
this.writeRateMs = writeRateMs
|
||||||
}
|
}
|
||||||
|
|
||||||
async put(value: any, writeRateMs: number = DEFAULT_WRITE_RATE_MS) {
|
async put(doc: any) {
|
||||||
return put(this.db, value, writeRateMs)
|
return put(this.db, doc, this.writeRateMs)
|
||||||
}
|
}
|
||||||
|
|
||||||
async get(id: string) {
|
async get(id: string) {
|
||||||
return get(this.db, id)
|
return get(this.db, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async remove(docOrId: any, rev?: any) {
|
||||||
|
return remove(this.db, docOrId, rev)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue