Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 0019e04

Browse files
committed
fix(getOrSet): fix missing { refresh } option
1 parent 7384bee commit 0019e04

File tree

4 files changed

+93
-21
lines changed

4 files changed

+93
-21
lines changed

package.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@
2020
"type": "git",
2121
"url": "git+https://github.com/blockai/cloud-cache.git"
2222
},
23-
"keywords": ["cache", "caching", "s3", "abstract-blob-store"],
23+
"keywords": [
24+
"cache",
25+
"caching",
26+
"s3",
27+
"abstract-blob-store"
28+
],
2429
"author": "Oli Lalonde <[email protected]> (https://syskall.com)",
2530
"license": "MIT",
2631
"bugs": {
@@ -40,6 +45,7 @@
4045
"cz-conventional-changelog": "^1.2.0",
4146
"eslint-config-blockai": "^1.0.1",
4247
"fs-blob-store": "^5.2.1",
48+
"mem": "^0.1.1",
4349
"nodemon": "^1.10.2",
4450
"randomstring": "^1.1.5",
4551
"request": "^2.74.0",
@@ -62,4 +68,4 @@
6268
"debug": "^2.2.0",
6369
"duplexify": "^3.4.5"
6470
}
65-
}
71+
}

src/index.js

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,20 @@ export default (store, {
9595
.catch(reject)
9696
})
9797

98-
const getOrSet = (key, fn, opts) => get(key)
99-
.catch((err) => {
100-
if (!(err instanceof KeyNotExistsError)) throw err
101-
// evaluate function as promise
102-
return Promise.resolve().then(() => fn())
103-
.then((value) => set(key, value, opts).then(() => value))
104-
})
98+
const getOrSet = (key, fn, opts = {}) => {
99+
const doCacheMiss = () => Promise.resolve()
100+
.then(() => fn())
101+
.then((value) => set(key, value, opts).then(() => value))
102+
103+
if (opts.refresh) return doCacheMiss()
104+
105+
return get(key)
106+
.catch((err) => {
107+
if (!(err instanceof KeyNotExistsError)) throw err
108+
// evaluate function as promise
109+
return doCacheMiss()
110+
})
111+
}
105112

106113
// Streaming API
107114
const getStream = (key) => {
@@ -133,7 +140,12 @@ export default (store, {
133140
const onError = (err) => {
134141
proxy.destroy(err)
135142
}
136-
get(key, { stream: true })
143+
144+
const getKey = opts.refresh
145+
? () => Promise.reject(new KeyNotExistsError(key))
146+
: () => get(key, { stream: true })
147+
148+
getKey()
137149
.then((rs) => {
138150
proxy.setReadable(rs)
139151
})

test/promise.test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,19 @@ test('ttl works', (t) => {
8686
})
8787
}, 300)
8888
})
89+
90+
test('cache.getOrSet (refresh works)', (t) => {
91+
const getLeet = () => new Promise((resolve) => {
92+
setTimeout(() => resolve(1337), 100)
93+
})
94+
const getEleet = () => new Promise((resolve) => {
95+
setTimeout(() => resolve(31337), 100)
96+
})
97+
return cache.getOrSet('refresh', getLeet).then((val) => {
98+
t.equal(val, 1337)
99+
return cache.getOrSet('refresh', getEleet, { refresh: true }).then((val2) => {
100+
t.equal(val2, 31337)
101+
})
102+
})
103+
})
104+

test/stream.test.js

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
import test from 'blue-tape'
22
import fs from 'fs'
33
import concat from 'concat-stream'
4+
import mem from 'mem'
45

56
import getCloudCache from './utils'
67

78
const cache = getCloudCache('stream')
89

9-
const poemPath = `${__dirname}/files/poem.txt`
10-
const poem = () => fs.createReadStream(poemPath)
11-
const poemStr = fs.readFileSync(poemPath)
10+
const file = mem((name) => {
11+
const filepath = `${__dirname}/files/${name}`
12+
const rs = () => fs.createReadStream(filepath)
13+
const buf = fs.readFileSync(filepath)
14+
return { path: filepath, rs, buf }
15+
})
16+
17+
const poem = file('poem.txt')
18+
const image = file('large.jpg')
19+
1220
// const devnull = () => fs.createWriteStream('/dev/null')
1321

1422
test('cache.sets', (t) => {
15-
poem().pipe(cache.sets('poem')).on('finish', () => {
23+
poem.rs().pipe(cache.sets('poem')).on('finish', () => {
1624
t.end()
1725
})
1826
})
@@ -21,8 +29,8 @@ test('cache.gets', (t) => {
2129
cache
2230
.gets('poem')
2331
.on('error', t.fail)
24-
.pipe(concat((str) => {
25-
t.equal(str.toString(), poemStr.toString())
32+
.pipe(concat((buf) => {
33+
t.equal(buf.toString(), poem.buf.toString())
2634
t.end()
2735
}))
2836
})
@@ -31,11 +39,11 @@ test('cache.getOrSets', (t) => {
3139
let callCount = 0
3240
const getPoemStream = () => {
3341
callCount++
34-
return poem()
42+
return poem.rs()
3543
}
3644

37-
const check = (str) => {
38-
t.equal(str.toString(), poemStr.toString())
45+
const check = (buf) => {
46+
t.equal(buf.toString(), poem.buf.toString())
3947
t.equal(callCount, 1)
4048
}
4149

@@ -56,11 +64,11 @@ test('cache.getOrSets, pipe later', (t) => {
5664
let callCount = 0
5765
const getPoemStream = () => {
5866
callCount++
59-
return poem()
67+
return poem.rs()
6068
}
6169

6270
const check = (str) => {
63-
t.equal(str.toString(), poemStr.toString())
71+
t.equal(str.toString(), poem.buf.toString())
6472
t.equal(callCount, 1)
6573
}
6674

@@ -79,3 +87,33 @@ test('cache.getOrSets, pipe later', (t) => {
7987
}))
8088
}, 300)
8189
})
90+
91+
test('cache.getOrSets, refresh=true', (t) => {
92+
const check = ({ buf }, buf2) => {
93+
t.ok(Buffer.compare(buf, buf2) === 0)
94+
}
95+
96+
const refresh = () => {
97+
cache.getOrSets('refresh', image.rs, { refresh: true })
98+
.on('error', t.fail)
99+
.pipe(concat((buf) => {
100+
check(image, buf)
101+
}))
102+
.on('finish', () => {
103+
cache.gets('refresh').pipe(concat((buf2) => {
104+
check(image, buf2)
105+
t.end()
106+
}))
107+
})
108+
}
109+
110+
cache.getOrSets('refresh', poem.rs)
111+
.on('error', t.fail)
112+
.on('data', () => {}) // make sure poem.rs is consumed
113+
.on('end', () => {
114+
cache.gets('refresh').pipe(concat((buf) => {
115+
check(poem, buf)
116+
refresh()
117+
}))
118+
})
119+
})

0 commit comments

Comments
 (0)