Skip to content

Commit

Permalink
fix(getOrSet): fix missing { refresh } option
Browse files Browse the repository at this point in the history
  • Loading branch information
olalonde committed Sep 7, 2016
1 parent 7384bee commit 0019e04
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 21 deletions.
10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@
"type": "git",
"url": "git+https://github.com/blockai/cloud-cache.git"
},
"keywords": ["cache", "caching", "s3", "abstract-blob-store"],
"keywords": [
"cache",
"caching",
"s3",
"abstract-blob-store"
],
"author": "Oli Lalonde <[email protected]> (https://syskall.com)",
"license": "MIT",
"bugs": {
Expand All @@ -40,6 +45,7 @@
"cz-conventional-changelog": "^1.2.0",
"eslint-config-blockai": "^1.0.1",
"fs-blob-store": "^5.2.1",
"mem": "^0.1.1",
"nodemon": "^1.10.2",
"randomstring": "^1.1.5",
"request": "^2.74.0",
Expand All @@ -62,4 +68,4 @@
"debug": "^2.2.0",
"duplexify": "^3.4.5"
}
}
}
28 changes: 20 additions & 8 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,20 @@ export default (store, {
.catch(reject)
})

const getOrSet = (key, fn, opts) => get(key)
.catch((err) => {
if (!(err instanceof KeyNotExistsError)) throw err
// evaluate function as promise
return Promise.resolve().then(() => fn())
.then((value) => set(key, value, opts).then(() => value))
})
const getOrSet = (key, fn, opts = {}) => {
const doCacheMiss = () => Promise.resolve()
.then(() => fn())
.then((value) => set(key, value, opts).then(() => value))

if (opts.refresh) return doCacheMiss()

return get(key)
.catch((err) => {
if (!(err instanceof KeyNotExistsError)) throw err
// evaluate function as promise
return doCacheMiss()
})
}

// Streaming API
const getStream = (key) => {
Expand Down Expand Up @@ -133,7 +140,12 @@ export default (store, {
const onError = (err) => {
proxy.destroy(err)
}
get(key, { stream: true })

const getKey = opts.refresh
? () => Promise.reject(new KeyNotExistsError(key))
: () => get(key, { stream: true })

getKey()
.then((rs) => {
proxy.setReadable(rs)
})
Expand Down
16 changes: 16 additions & 0 deletions test/promise.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,19 @@ test('ttl works', (t) => {
})
}, 300)
})

test('cache.getOrSet (refresh works)', (t) => {
const getLeet = () => new Promise((resolve) => {
setTimeout(() => resolve(1337), 100)
})
const getEleet = () => new Promise((resolve) => {
setTimeout(() => resolve(31337), 100)
})
return cache.getOrSet('refresh', getLeet).then((val) => {
t.equal(val, 1337)
return cache.getOrSet('refresh', getEleet, { refresh: true }).then((val2) => {
t.equal(val2, 31337)
})
})
})

60 changes: 49 additions & 11 deletions test/stream.test.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
import test from 'blue-tape'
import fs from 'fs'
import concat from 'concat-stream'
import mem from 'mem'

import getCloudCache from './utils'

const cache = getCloudCache('stream')

const poemPath = `${__dirname}/files/poem.txt`
const poem = () => fs.createReadStream(poemPath)
const poemStr = fs.readFileSync(poemPath)
const file = mem((name) => {
const filepath = `${__dirname}/files/${name}`
const rs = () => fs.createReadStream(filepath)
const buf = fs.readFileSync(filepath)
return { path: filepath, rs, buf }
})

const poem = file('poem.txt')
const image = file('large.jpg')

// const devnull = () => fs.createWriteStream('/dev/null')

test('cache.sets', (t) => {
poem().pipe(cache.sets('poem')).on('finish', () => {
poem.rs().pipe(cache.sets('poem')).on('finish', () => {
t.end()
})
})
Expand All @@ -21,8 +29,8 @@ test('cache.gets', (t) => {
cache
.gets('poem')
.on('error', t.fail)
.pipe(concat((str) => {
t.equal(str.toString(), poemStr.toString())
.pipe(concat((buf) => {
t.equal(buf.toString(), poem.buf.toString())
t.end()
}))
})
Expand All @@ -31,11 +39,11 @@ test('cache.getOrSets', (t) => {
let callCount = 0
const getPoemStream = () => {
callCount++
return poem()
return poem.rs()
}

const check = (str) => {
t.equal(str.toString(), poemStr.toString())
const check = (buf) => {
t.equal(buf.toString(), poem.buf.toString())
t.equal(callCount, 1)
}

Expand All @@ -56,11 +64,11 @@ test('cache.getOrSets, pipe later', (t) => {
let callCount = 0
const getPoemStream = () => {
callCount++
return poem()
return poem.rs()
}

const check = (str) => {
t.equal(str.toString(), poemStr.toString())
t.equal(str.toString(), poem.buf.toString())
t.equal(callCount, 1)
}

Expand All @@ -79,3 +87,33 @@ test('cache.getOrSets, pipe later', (t) => {
}))
}, 300)
})

test('cache.getOrSets, refresh=true', (t) => {
const check = ({ buf }, buf2) => {
t.ok(Buffer.compare(buf, buf2) === 0)
}

const refresh = () => {
cache.getOrSets('refresh', image.rs, { refresh: true })
.on('error', t.fail)
.pipe(concat((buf) => {
check(image, buf)
}))
.on('finish', () => {
cache.gets('refresh').pipe(concat((buf2) => {
check(image, buf2)
t.end()
}))
})
}

cache.getOrSets('refresh', poem.rs)
.on('error', t.fail)
.on('data', () => {}) // make sure poem.rs is consumed
.on('end', () => {
cache.gets('refresh').pipe(concat((buf) => {
check(poem, buf)
refresh()
}))
})
})

0 comments on commit 0019e04

Please sign in to comment.