UNPKG

1.85 kBJavaScriptView Raw
1/** Copyright (c) 2018 Uber Technologies, Inc.
2 *
3 * This source code is licensed under the MIT license found in the
4 * LICENSE file in the root directory of this source tree.
5 *
6 * @flow
7 */
8/* eslint-env node */
9
10const fs = require('fs');
11const path = require('path');
12const zlib = require('zlib');
13const {promisify} = require('util');
14
15const makeDir = require('make-dir');
16
17const readFile = promisify(fs.readFile);
18const writeFile = promisify(fs.writeFile);
19const gunzip = promisify(zlib.gunzip);
20const gzip = promisify(zlib.gzip);
21
22module.exports = class PersistentDiskCache /*::<T>*/ {
23 /*::
24 cacheDirectory: string;
25 */
26 constructor(cacheDirectory /*:string*/) {
27 this.cacheDirectory = cacheDirectory;
28 }
29 async get(cacheKey /*: string*/, thunk /*: () => T */) {
30 const filepath = getFilePath(this.cacheDirectory, cacheKey);
31
32 try {
33 return await read(filepath);
34 } catch (err) {
35 // Simply ignore cache if read fails
36 }
37
38 const result = thunk();
39
40 try {
41 await makeDir(this.cacheDirectory);
42 await write(filepath, result);
43 } catch (err) {
44 // If write fails, oh well
45 }
46
47 return result;
48 }
49
50 async read(cacheKey /*: string*/) {
51 const path = getFilePath(this.cacheDirectory, cacheKey);
52 return await read(path);
53 }
54
55 exists(cacheKey /*: string*/) {
56 const filepath = getFilePath(this.cacheDirectory, cacheKey);
57 return fs.existsSync(filepath);
58 }
59};
60async function read(path /*: string*/) {
61 const data = await readFile(path);
62 const content = await gunzip(data);
63 return JSON.parse(content);
64}
65async function write(path /*: string*/, result) {
66 const content = JSON.stringify(result);
67 const data = await gzip(content);
68 return await writeFile(path, data);
69}
70
71function getFilePath(dirname, cacheKey) {
72 return path.join(dirname, `${cacheKey}.json.gz`);
73}