Skip to content

Commit

Permalink
code cache - cleanup in prep for chrome based code loading
Browse files Browse the repository at this point in the history
  • Loading branch information
bpasero committed Jun 8, 2021
1 parent e4373f7 commit 2cb7b42
Show file tree
Hide file tree
Showing 18 changed files with 302 additions and 293 deletions.
6 changes: 3 additions & 3 deletions src/bootstrap-amd.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ exports.load = function (entrypoint, onLoad, onError) {
return;
}

// cached data config
if (process.env['VSCODE_NODE_CACHED_DATA_DIR']) {
// code cache config
if (process.env['VSCODE_CODE_CACHE_PATH']) {
loader.config({
nodeCachedData: {
path: process.env['VSCODE_NODE_CACHED_DATA_DIR'],
path: process.env['VSCODE_CODE_CACHE_PATH'],
seed: entrypoint
}
});
Expand Down
4 changes: 2 additions & 2 deletions src/bootstrap-window.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,9 @@
}

// Cached data config
if (configuration.nodeCachedDataDir) {
if (configuration.codeCachePath) {
loaderConfig.nodeCachedData = {
path: configuration.nodeCachedDataDir,
path: configuration.codeCachePath,
seed: modulePaths.join('')
};
}
Expand Down
86 changes: 43 additions & 43 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ const args = parseCLIArgs();
const userDataPath = getUserDataPath(args);
app.setPath('userData', userDataPath);

// Resolve code cache path
const codeCachePath = getCodeCachePath();

// Configure static command line arguments
const argvConfig = configureCommandlineSwitchesSync(args);

Expand Down Expand Up @@ -71,9 +74,6 @@ protocol.registerSchemesAsPrivileged([
// Global app listeners
registerListeners();

// Cached data
const nodeCachedDataDir = getNodeCachedDir();

/**
* Support user defined locale: load it early before app('ready')
* to have more things running in parallel.
Expand Down Expand Up @@ -108,14 +108,14 @@ app.once('ready', function () {
/**
* Main startup routine
*
* @param {string | undefined} cachedDataDir
* @param {string | undefined} codeCachePath
* @param {NLSConfiguration} nlsConfig
*/
function startup(cachedDataDir, nlsConfig) {
function startup(codeCachePath, nlsConfig) {
nlsConfig._languagePackSupport = true;

process.env['VSCODE_NLS_CONFIG'] = JSON.stringify(nlsConfig);
process.env['VSCODE_NODE_CACHED_DATA_DIR'] = cachedDataDir || '';
process.env['VSCODE_CODE_CACHE_PATH'] = codeCachePath || '';

// Load main in AMD
perf.mark('code/willLoadMainBundle');
Expand All @@ -128,9 +128,9 @@ async function onReady() {
perf.mark('code/mainAppReady');

try {
const [cachedDataDir, nlsConfig] = await Promise.all([nodeCachedDataDir.ensureExists(), resolveNlsConfiguration()]);
const [, nlsConfig] = await Promise.all([mkdirpIgnoreError(codeCachePath), resolveNlsConfiguration()]);

startup(cachedDataDir, nlsConfig);
startup(codeCachePath, nlsConfig);
} catch (error) {
console.error(error);
}
Expand Down Expand Up @@ -499,46 +499,28 @@ function registerListeners() {
}

/**
* @returns {{ ensureExists: () => Promise<string | undefined> }}
* @returns {string | undefined} the location to use for the code cache
* or `undefined` if disabled.
*/
function getNodeCachedDir() {
return new class {

constructor() {
this.value = this.compute();
}
function getCodeCachePath() {

async ensureExists() {
if (typeof this.value === 'string') {
try {
await mkdirp(this.value);

return this.value;
} catch (error) {
// ignore
}
}
}

compute() {
if (process.argv.indexOf('--no-cached-data') > 0) {
return undefined;
}
// explicitly disabled via CLI args
if (process.argv.indexOf('--no-cached-data') > 0) {
return undefined;
}

// IEnvironmentService.isBuilt
if (process.env['VSCODE_DEV']) {
return undefined;
}
// running out of sources
if (process.env['VSCODE_DEV']) {
return undefined;
}

// find commit id
const commit = product.commit;
if (!commit) {
return undefined;
}
// require commit id
const commit = product.commit;
if (!commit) {
return undefined;
}

return path.join(userDataPath, 'CachedData', commit);
}
};
return path.join(userDataPath, 'CachedData', commit);
}

/**
Expand All @@ -553,6 +535,24 @@ function mkdirp(dir) {
});
}

/**
* @param {string | undefined} dir
* @returns {Promise<string | undefined>}
*/
async function mkdirpIgnoreError(dir) {
if (typeof dir === 'string') {
try {
await mkdirp(dir);

return dir;
} catch (error) {
// ignore
}
}

return undefined;
}

//#region NLS Support

/**
Expand Down
4 changes: 2 additions & 2 deletions src/vs/base/parts/sandbox/common/sandboxTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export interface ISandboxConfiguration {
zoomLevel?: number;

/**
* @deprecated to be removed soon
* Location of V8 code cache.
*/
nodeCachedDataDir?: string;
codeCachePath?: string;
}
2 changes: 1 addition & 1 deletion src/vs/base/test/common/processes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ suite('Processes', () => {
VSCODE_NLS_CONFIG: 'x',
VSCODE_PORTABLE: 'x',
VSCODE_PID: 'x',
VSCODE_NODE_CACHED_DATA_DIR: 'x',
VSCODE_CODE_CACHE_PATH: 'x',
VSCODE_NEW_VAR: 'x',
GDK_PIXBUF_MODULE_FILE: 'x',
GDK_PIXBUF_MODULEDIR: 'x',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { basename, dirname, join } from 'vs/base/common/path';
import { onUnexpectedError } from 'vs/base/common/errors';
import { Disposable } from 'vs/base/common/lifecycle';
import { Promises, rimraf } from 'vs/base/node/pfs';
import { IProductService } from 'vs/platform/product/common/productService';
import { RunOnceScheduler } from 'vs/base/common/async';
import { ILogService } from 'vs/platform/log/common/log';

export class CodeCacheCleaner extends Disposable {

private readonly _DataMaxAge = this.productService.quality !== 'stable'
? 1000 * 60 * 60 * 24 * 7 // roughly 1 week (insiders)
: 1000 * 60 * 60 * 24 * 30 * 3; // roughly 3 months (stable)

constructor(
currentCodeCachePath: string | undefined,
@IProductService private readonly productService: IProductService,
@ILogService private readonly logService: ILogService
) {
super();

// Cached data is stored as user data and we run a cleanup task everytime
// the editor starts. The strategy is to delete all files that are older than
// 3 months (1 week respectively)
if (currentCodeCachePath) {
const scheduler = this._register(new RunOnceScheduler(() => {
this.cleanUpCodeCaches(currentCodeCachePath);
}, 30 * 1000 /* after 30s */));
scheduler.schedule();
}
}

private async cleanUpCodeCaches(currentCodeCachePath: string): Promise<void> {
this.logService.info('[code cache cleanup]: Starting to clean up old code cache folders.');

try {
const now = Date.now();

// The folder which contains folders of cached data.
// Each of these folders is partioned per commit
const codeCacheRootPath = dirname(currentCodeCachePath);
const currentCodeCache = basename(currentCodeCachePath);

const codeCaches = await Promises.readdir(codeCacheRootPath);
await Promise.all(codeCaches.map(async codeCache => {
if (codeCache === currentCodeCache) {
return; // not the current cache folder
}

// Delete cache folder if old enough
const codeCacheEntryPath = join(codeCacheRootPath, codeCache);
const codeCacheEntryStat = await Promises.stat(codeCacheEntryPath);
if (codeCacheEntryStat.isDirectory() && (now - codeCacheEntryStat.mtime.getTime()) > this._DataMaxAge) {
this.logService.info(`[code cache cleanup]: Removing code cache folder ${codeCache}.`);

return rimraf(codeCacheEntryPath);
}
}));
} catch (error) {
onUnexpectedError(error);
}
}
}
Loading

0 comments on commit 2cb7b42

Please sign in to comment.