/** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format * */ "use strict"; const FileStore = require("./FileStore"); const fs = require("fs"); const path = require("path"); // List all files in a directory in Node.js recursively in a synchronous fashion const walkSync = function(dir, filelist) { const files = fs.readdirSync(dir); filelist = filelist || []; files.forEach(function(file) { const fullPath = path.join(dir, file); const stats = fs.statSync(fullPath); if (stats.isDirectory()) { filelist = walkSync(fullPath + path.sep, filelist); } else { filelist.push({ path: fullPath, stats }); } }); return filelist; }; function get(property, defaultValue) { if (property == null) { return defaultValue; } return property; } /** * A FileStore that cleans itself up in a given interval */ class AutoCleanFileStore extends FileStore { constructor(opts) { super({ root: opts.root }); this._intervalMs = get(opts.intervalMs, 10 * 60 * 1000); // 10 minutes this._cleanupThresholdMs = get( opts.cleanupThresholdMs, 3 * 24 * 60 * 60 * 1000 // 3 days ); this._scheduleCleanup(); } _scheduleCleanup() { setTimeout(this._doCleanup.bind(this), this._intervalMs); } _doCleanup() { const files = walkSync(this._root, []); let warned = false; files.forEach(file => { if (file.stats.mtimeMs < Date.now() - this._cleanupThresholdMs) { try { fs.unlinkSync(file.path); } catch (e) { if (!warned) { console.warn( "Problem cleaning up cache for " + file.path + ": " + e.message ); warned = true; } } } }); this._scheduleCleanup(); } } module.exports = AutoCleanFileStore;