feat(core): remove old cache records
This commit is contained in:
parent
dddc1b1e6c
commit
f84c55d5aa
@ -4,7 +4,9 @@ import { findWorkspaceRoot } from './find-workspace-root';
|
||||
|
||||
const workspace = findWorkspaceRoot(process.cwd());
|
||||
|
||||
setUpOutputWatching();
|
||||
if (process.env.NX_TERMINAL_OUTPUT_PATH) {
|
||||
setUpOutputWatching();
|
||||
}
|
||||
requireCli();
|
||||
|
||||
function requireCli() {
|
||||
|
||||
@ -7,6 +7,7 @@ import { join } from 'path';
|
||||
import { Hasher } from './hasher';
|
||||
import * as fsExtra from 'fs-extra';
|
||||
import { DefaultTasksRunnerOptions } from './tasks-runner-v2';
|
||||
import { fork, spawn } from 'child_process';
|
||||
|
||||
export type CachedResult = { terminalOutput: string; outputsPath: string };
|
||||
export type TaskWithCachedResult = { task: Task; cachedResult: CachedResult };
|
||||
@ -40,6 +41,35 @@ export class Cache {
|
||||
private readonly options: DefaultTasksRunnerOptions
|
||||
) {}
|
||||
|
||||
removeOldCacheRecords() {
|
||||
/**
|
||||
* Even though spawning a process is fast, we don't want to do it every time
|
||||
* the user runs a command. Instead, we want to do it once in a while.
|
||||
*/
|
||||
const shouldSpawnProcess = Math.floor(Math.random() * 50) === 1;
|
||||
if (shouldSpawnProcess) {
|
||||
const scriptPath = join(
|
||||
this.root,
|
||||
'node_modules',
|
||||
'@nrwl',
|
||||
'workspace',
|
||||
'src',
|
||||
'tasks-runner',
|
||||
'remove-old-cache-records.js'
|
||||
);
|
||||
try {
|
||||
const p = spawn('node', [`"${scriptPath}"`, `"${this.cachePath}"`], {
|
||||
stdio: 'ignore',
|
||||
detached: true
|
||||
});
|
||||
p.unref();
|
||||
} catch (e) {
|
||||
console.log(`Unable to start remove-old-cache-records script:`);
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async get(task: Task): Promise<CachedResult> {
|
||||
if (!this.cacheConfig.isCacheableTask(task)) return null;
|
||||
|
||||
@ -60,7 +90,6 @@ export class Cache {
|
||||
}
|
||||
|
||||
async put(task: Task, terminalOutputPath: string, folders: string[]) {
|
||||
if (!this.cacheConfig.isCacheableTask(task)) return;
|
||||
const terminalOutput = readFileSync(terminalOutputPath).toString();
|
||||
const hash = await this.hasher.hash(task);
|
||||
const td = join(this.cachePath, hash);
|
||||
@ -115,7 +144,11 @@ export class Cache {
|
||||
}
|
||||
|
||||
async temporaryOutputPath(task: Task) {
|
||||
return join(this.terminalOutputsDir, await this.hasher.hash(task));
|
||||
if (this.cacheConfig.isCacheableTask(task)) {
|
||||
return join(this.terminalOutputsDir, await this.hasher.hash(task));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private async getFromLocalDir(task: Task) {
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
import * as fs from 'fs';
|
||||
import * as fsExtra from 'fs-extra';
|
||||
import * as path from 'path';
|
||||
|
||||
const WEEK_IN_MS = 1000 * 60 * 60 * 24 * 7;
|
||||
|
||||
const folder = process.argv[2];
|
||||
|
||||
removeOld(terminalOutputs());
|
||||
removeOld(cachedFiles());
|
||||
|
||||
function terminalOutputs() {
|
||||
try {
|
||||
return fs.readdirSync(path.join(folder, 'terminalOutputs'));
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function cachedFiles() {
|
||||
try {
|
||||
return fs.readdirSync(folder).filter(f => !f.endsWith('terminalOutputs'));
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function removeOld(records: string[]) {
|
||||
try {
|
||||
const time = mostRecentMTime(records);
|
||||
|
||||
records.forEach(r => {
|
||||
const child = path.join(folder, r);
|
||||
try {
|
||||
const s = fs.statSync(child);
|
||||
if (time - s.mtimeMs > WEEK_IN_MS) {
|
||||
if (s.isDirectory()) {
|
||||
try {
|
||||
fsExtra.removeSync(`${child}.commit`);
|
||||
} catch (e) {}
|
||||
}
|
||||
fsExtra.removeSync(child);
|
||||
}
|
||||
} catch (e) {}
|
||||
});
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
function mostRecentMTime(records: string[]) {
|
||||
let mostRecentTime = 0;
|
||||
records.forEach(r => {
|
||||
const child = path.join(folder, r);
|
||||
try {
|
||||
const s = fs.statSync(child);
|
||||
if (s.mtimeMs > mostRecentTime) {
|
||||
mostRecentTime = s.mtimeMs;
|
||||
}
|
||||
} catch (e) {}
|
||||
});
|
||||
return mostRecentTime;
|
||||
}
|
||||
@ -28,6 +28,7 @@ export class TaskOrchestrator {
|
||||
|
||||
const r1 = await this.applyCachedResults(cached);
|
||||
const r2 = await this.runRest(rest);
|
||||
this.cache.removeOldCacheRecords();
|
||||
return [...r1, ...r2];
|
||||
}
|
||||
|
||||
@ -109,12 +110,16 @@ export class TaskOrchestrator {
|
||||
return this.cache.temporaryOutputPath(task).then(outputPath => {
|
||||
return new Promise((res, rej) => {
|
||||
try {
|
||||
const env = { ...process.env };
|
||||
if (outputPath) {
|
||||
env.NX_TERMINAL_OUTPUT_PATH = outputPath;
|
||||
}
|
||||
const p = fork(this.getCommand(), this.getCommandArgs(task), {
|
||||
stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
|
||||
env: { ...process.env, NX_TERMINAL_OUTPUT_PATH: outputPath }
|
||||
env
|
||||
});
|
||||
p.on('close', code => {
|
||||
if (code === 0) {
|
||||
if (outputPath && code === 0) {
|
||||
this.cache.put(task, outputPath, taskOutputs).then(() => {
|
||||
res(code);
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user