/**
* 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;