testplane
Version:
Tests framework based on mocha and wdio
123 lines • 5.46 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.setCachedSelectivityFile = exports.getCachedSelectivityFile = exports.hasCachedSelectivityFile = exports.CacheType = void 0;
const node_os_1 = __importDefault(require("node:os"));
const node_path_1 = __importDefault(require("node:path"));
const node_perf_hooks_1 = require("node:perf_hooks");
const p_limit_1 = __importDefault(require("p-limit"));
const proper_lockfile_1 = __importDefault(require("proper-lockfile"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const crypto_1 = require("../../../utils/crypto");
const constants_1 = require("./constants");
exports.CacheType = {
TestFile: "t",
Asset: "a",
CssSessionCache: "cs",
SourceMapParseResult: "sm",
};
// Cache is considered fresh if it was created after process start
const tmpDir = node_path_1.default.join(node_os_1.default.tmpdir(), constants_1.SELECTIVITY_CACHE_DIRECTIRY);
// https://nodejs.org/api/cli.html#uv_threadpool_sizesize
const libUVLimited = (0, p_limit_1.default)((process.env.UV_THREADPOOL_SIZE && Number(process.env.UV_THREADPOOL_SIZE)) || 16);
const ensureSelectivityCacheDirectory = async () => {
await libUVLimited(() => fs_extra_1.default.ensureDir(tmpDir));
};
const wasModifiedAfterProcessStart = async (flagFilePath) => {
try {
const stats = await libUVLimited(() => fs_extra_1.default.stat(flagFilePath));
return stats.mtimeMs >= node_perf_hooks_1.performance.timeOrigin;
}
catch {
return false;
}
};
const getHashName = (cacheType, cacheKey) => {
// Not hashing cache key for session cache as it will just increase collision chance without any profit
return cacheType + (cacheType === exports.CacheType.CssSessionCache ? cacheKey : (0, crypto_1.getMD5)(cacheKey));
};
const hasCachedSelectivityFile = async (cacheType, key) => {
if (!key) {
throw new Error("Attepted to check existance of cache with empty key");
}
const hashName = getHashName(cacheType, key);
const cacheFilePath = node_path_1.default.join(tmpDir, hashName);
const flagFilePath = cacheFilePath + constants_1.SELECTIVITY_CACHE_READY_SUFFIX;
return wasModifiedAfterProcessStart(flagFilePath);
};
exports.hasCachedSelectivityFile = hasCachedSelectivityFile;
const getCachedSelectivityFile = async (cacheType, key) => {
if (!key) {
throw new Error("Attepted to read cache with empty key");
}
const hashName = getHashName(cacheType, key);
const cacheFilePath = node_path_1.default.join(tmpDir, hashName);
const flagFilePath = cacheFilePath + constants_1.SELECTIVITY_CACHE_READY_SUFFIX;
if (await wasModifiedAfterProcessStart(flagFilePath)) {
const cacheContents = await libUVLimited(() => fs_extra_1.default.readFile(cacheFilePath, "utf8")).catch(() => null);
return cacheContents;
}
// Writing cache right now, should wait a little bit
if (await wasModifiedAfterProcessStart(cacheFilePath)) {
for (let i = 0; i < 10; i++) {
if (await wasModifiedAfterProcessStart(flagFilePath)) {
const cacheContents = await libUVLimited(() => fs_extra_1.default.readFile(cacheFilePath, "utf8")).catch(() => null);
return cacheContents;
}
await new Promise(resolve => setTimeout(resolve, 50));
}
}
return null;
};
exports.getCachedSelectivityFile = getCachedSelectivityFile;
const setCachedSelectivityFile = async (cacheType, key, utf8Contents, { overwrite = false } = {}) => {
if (!key) {
throw new Error("Attepted to write cache with empty key");
}
const hashName = getHashName(cacheType, key);
const cacheFilePath = node_path_1.default.join(tmpDir, hashName);
const flagFilePath = cacheFilePath + constants_1.SELECTIVITY_CACHE_READY_SUFFIX;
// Cache was already written
if (!overwrite && (await wasModifiedAfterProcessStart(flagFilePath))) {
return;
}
await ensureSelectivityCacheDirectory();
const releaseLock = await proper_lockfile_1.default
.lock(flagFilePath, {
stale: 5000,
update: 1000,
retries: {
factor: 2,
minTimeout: 50,
maxTimeout: 200,
retries: overwrite ? 30 : 1,
},
realpath: false,
})
.catch(() => null);
// Other process already aquired writing-lock
if (!releaseLock) {
return;
}
// Cache was written while trying to get lock
if (!overwrite && (await wasModifiedAfterProcessStart(flagFilePath))) {
await releaseLock();
return;
}
try {
await libUVLimited(() => fs_extra_1.default.writeFile(cacheFilePath, utf8Contents, { encoding: "utf8" })).catch(cause => {
throw new Error(`Couldn't write cache to "${cacheFilePath}"`, { cause });
});
// Using "writeFile" to trigger "mtime" update even if file exists
await libUVLimited(() => fs_extra_1.default.writeFile(flagFilePath, "")).catch(cause => {
throw new Error(`Couldn't mark cache as fresh at "${cacheFilePath}"`, { cause });
});
}
finally {
await releaseLock();
}
};
exports.setCachedSelectivityFile = setCachedSelectivityFile;
//# sourceMappingURL=fs-cache.js.map