From e52b2b9e287d6aa264bb4d14d66675dd210181bd Mon Sep 17 00:00:00 2001 From: Sebastian Benz Date: Mon, 29 Mar 2021 21:17:57 +0200 Subject: [PATCH] Use os.tmpDir for file system cache Fallback to in-memory cache if no fs access. Fixes #1178 --- packages/core/lib/FileSystemCache.js | 23 ++++++++++++++----- packages/core/spec/lib/FileSystemCacheSpec.js | 11 +++++++-- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/packages/core/lib/FileSystemCache.js b/packages/core/lib/FileSystemCache.js index 96e5c432c..a9efcff38 100644 --- a/packages/core/lib/FileSystemCache.js +++ b/packages/core/lib/FileSystemCache.js @@ -17,20 +17,34 @@ const fs = require('fs').promises; const {existsSync, mkdirSync} = require('fs'); const crypto = require('crypto'); +const os = require('os'); const log = require('./Log'); const LRUCache = require('lru-cache'); const path = require('path'); const DEFAULT_OPTS = { - baseDir: path.join(__dirname, '.cache'), log, maxItems: 50, }; class FileSystemCache { - static create(opts = {}) { - return new FileSystemCache(Object.assign(DEFAULT_OPTS, opts)); + static create(customOpts = {}) { + const opts = Object.assign(DEFAULT_OPTS, customOpts); + // Try to create a tmp directory... + try { + if (!opts.baseDir) { + opts.baseDir = path.join(os.tmpdir(), 'ampproject-toolbox-optimizer'); + } + if (!existsSync(opts.baseDir)) { + mkdirSync(opts.baseDir); + } + } catch (e) { + log.debug('No filesystem access, falling back to in-memory cache only', e); + // ... if this fails, we have no write access to the fs, use a simple memory cache instead + return new LRUCache(opts.maxItems); + } + return new FileSystemCache(opts); } constructor(opts) { @@ -57,9 +71,6 @@ class FileSystemCache { async set(key, value) { try { this.cache.set(key, value); - if (!existsSync(this.opts.baseDir)) { - mkdirSync(this.opts.baseDir); - } const cacheFile = this.createCacheFileName(key); return fs.writeFile(cacheFile, JSON.stringify(value, null, ''), 'utf-8'); } catch (e) { diff --git a/packages/core/spec/lib/FileSystemCacheSpec.js b/packages/core/spec/lib/FileSystemCacheSpec.js index 749370bbe..144619a4e 100644 --- a/packages/core/spec/lib/FileSystemCacheSpec.js +++ b/packages/core/spec/lib/FileSystemCacheSpec.js @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - const FileSystemCache = require('../../lib/FileSystemCache.js'); let cache; @@ -22,7 +21,6 @@ beforeEach(async () => { cache = FileSystemCache.create(); await cache.clear(); }); -//afterEach(async () => await cache.clear()); test('returns null by default', async () => { const result = await cache.get('key'); @@ -39,3 +37,12 @@ test('returns cached value', async () => { const result = await cache.get('key'); expect(result).toBe('value'); }); + +test('falls back to in memory cache', async () => { + cache = FileSystemCache.create({ + baseDir: {}, // invalid pathname to trigger exception + }); + await cache.set('key', 'value'); + const result = await cache.get('key'); + expect(result).toBe('value'); +});