152 lines
4.1 KiB
JavaScript
152 lines
4.1 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
/**
|
|
* A worker dedicated for the I/O component of PageThumbs storage.
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
/* import-globals-from /toolkit/components/workerloader/require.js */
|
|
importScripts("resource://gre/modules/workers/require.js");
|
|
|
|
var PromiseWorker = require("resource://gre/modules/workers/PromiseWorker.js");
|
|
|
|
var worker = new PromiseWorker.AbstractWorker();
|
|
worker.dispatch = function (method, args = []) {
|
|
return Agent[method](...args);
|
|
};
|
|
worker.postMessage = function (message, ...transfers) {
|
|
self.postMessage(message, ...transfers);
|
|
};
|
|
worker.close = function () {
|
|
self.close();
|
|
};
|
|
|
|
self.addEventListener("message", msg => worker.handleMessage(msg));
|
|
self.addEventListener("unhandledrejection", function (error) {
|
|
throw error.reason;
|
|
});
|
|
|
|
var Agent = {
|
|
// Checks if the specified file exists and has an age less than as
|
|
// specifed (in seconds).
|
|
async isFileRecent(path, maxAge) {
|
|
try {
|
|
let stat = await IOUtils.stat(path);
|
|
let maxDate = new Date();
|
|
maxDate.setSeconds(maxDate.getSeconds() - maxAge);
|
|
return stat.lastModified > maxDate;
|
|
} catch (ex) {
|
|
if (!(ex instanceof DOMException)) {
|
|
throw ex;
|
|
}
|
|
// file doesn't exist (or can't be stat'd) - must be stale.
|
|
return false;
|
|
}
|
|
},
|
|
|
|
async remove(path) {
|
|
try {
|
|
await IOUtils.remove(path);
|
|
return true;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
},
|
|
|
|
async expireFilesInDirectory(path, filesToKeep, minChunkSize) {
|
|
let entries = await this.getFileEntriesInDirectory(path, filesToKeep);
|
|
let limit = Math.max(minChunkSize, Math.round(entries.length / 2));
|
|
|
|
for (let entry of entries) {
|
|
await this.remove(entry);
|
|
|
|
// Check if we reached the limit of files to remove.
|
|
if (--limit <= 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
},
|
|
|
|
async getFileEntriesInDirectory(path, skipFiles) {
|
|
let children = await IOUtils.getChildren(path);
|
|
let skip = new Set(skipFiles);
|
|
|
|
let entries = [];
|
|
for (let entry of children) {
|
|
let stat = await IOUtils.stat(entry);
|
|
if (stat.type === "regular" && !skip.has(PathUtils.filename(entry))) {
|
|
entries.push(entry);
|
|
}
|
|
}
|
|
return entries;
|
|
},
|
|
|
|
async moveOrDeleteAllThumbnails(pathFrom, pathTo) {
|
|
await IOUtils.makeDirectory(pathTo);
|
|
if (pathFrom == pathTo) {
|
|
return true;
|
|
}
|
|
let children = await IOUtils.getChildren(pathFrom);
|
|
for (let entry of children) {
|
|
let stat = await IOUtils.stat(entry);
|
|
if (stat.type !== "regular") {
|
|
continue;
|
|
}
|
|
|
|
let fileName = PathUtils.filename(entry);
|
|
let from = PathUtils.join(pathFrom, fileName);
|
|
let to = PathUtils.join(pathTo, fileName);
|
|
|
|
try {
|
|
await IOUtils.move(from, to, { noOverwrite: true });
|
|
} catch (e) {
|
|
await IOUtils.remove(from);
|
|
}
|
|
}
|
|
|
|
try {
|
|
await IOUtils.remove(pathFrom, { recursive: true });
|
|
} catch (e) {
|
|
// This could fail if there's something in
|
|
// the folder we're not permitted to remove.
|
|
}
|
|
|
|
return true;
|
|
},
|
|
|
|
writeAtomic(path, buffer, options) {
|
|
return IOUtils.write(path, buffer, options);
|
|
},
|
|
|
|
makeDir(path, options) {
|
|
return IOUtils.makeDirectory(path, options);
|
|
},
|
|
|
|
copy(source, dest, options) {
|
|
return IOUtils.copy(source, dest, options);
|
|
},
|
|
|
|
async wipe(path) {
|
|
let children = await IOUtils.getChildren(path);
|
|
try {
|
|
await Promise.all(children.map(entry => IOUtils.remove(entry)));
|
|
} catch (ex) {
|
|
// If a file cannot be removed, we should still continue.
|
|
// This can happen at least for any of the following reasons:
|
|
// - access denied;
|
|
// - file has been removed recently during a previous wipe
|
|
// and the file system has not flushed that yet (yes, this
|
|
// can happen under Windows);
|
|
// - file has been removed by the user or another process.
|
|
}
|
|
},
|
|
|
|
exists(path) {
|
|
return IOUtils.exists(path);
|
|
},
|
|
};
|