Path: blob/main/src/vs/code/electron-utility/sharedProcess/contrib/codeCacheCleaner.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { promises } from 'fs';6import { RunOnceScheduler } from '../../../../base/common/async.js';7import { onUnexpectedError } from '../../../../base/common/errors.js';8import { Disposable } from '../../../../base/common/lifecycle.js';9import { basename, dirname, join } from '../../../../base/common/path.js';10import { Promises } from '../../../../base/node/pfs.js';11import { ILogService } from '../../../../platform/log/common/log.js';12import { IProductService } from '../../../../platform/product/common/productService.js';1314export class CodeCacheCleaner extends Disposable {1516private readonly dataMaxAge: number;1718constructor(19currentCodeCachePath: string | undefined,20@IProductService productService: IProductService,21@ILogService private readonly logService: ILogService22) {23super();2425this.dataMaxAge = productService.quality !== 'stable'26? 1000 * 60 * 60 * 24 * 7 // roughly 1 week (insiders)27: 1000 * 60 * 60 * 24 * 30 * 3; // roughly 3 months (stable)2829// Cached data is stored as user data and we run a cleanup task every time30// the editor starts. The strategy is to delete all files that are older than31// 3 months (1 week respectively)32if (currentCodeCachePath) {33const scheduler = this._register(new RunOnceScheduler(() => {34this.cleanUpCodeCaches(currentCodeCachePath);35}, 30 * 1000 /* after 30s */));36scheduler.schedule();37}38}3940private async cleanUpCodeCaches(currentCodeCachePath: string): Promise<void> {41this.logService.trace('[code cache cleanup]: Starting to clean up old code cache folders.');4243try {44const now = Date.now();4546// The folder which contains folders of cached data.47// Each of these folders is partioned per commit48const codeCacheRootPath = dirname(currentCodeCachePath);49const currentCodeCache = basename(currentCodeCachePath);5051const codeCaches = await Promises.readdir(codeCacheRootPath);52await Promise.all(codeCaches.map(async codeCache => {53if (codeCache === currentCodeCache) {54return; // not the current cache folder55}5657// Delete cache folder if old enough58const codeCacheEntryPath = join(codeCacheRootPath, codeCache);59const codeCacheEntryStat = await promises.stat(codeCacheEntryPath);60if (codeCacheEntryStat.isDirectory() && (now - codeCacheEntryStat.mtime.getTime()) > this.dataMaxAge) {61this.logService.trace(`[code cache cleanup]: Removing code cache folder ${codeCache}.`);6263return Promises.rm(codeCacheEntryPath);64}65}));66} catch (error) {67onUnexpectedError(error);68}69}70}717273