Path: blob/main/src/vs/code/electron-utility/sharedProcess/contrib/storageDataCleaner.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 { RunOnceScheduler } from '../../../../base/common/async.js';6import { onUnexpectedError } from '../../../../base/common/errors.js';7import { Disposable } from '../../../../base/common/lifecycle.js';8import { join } from '../../../../base/common/path.js';9import { Promises } from '../../../../base/node/pfs.js';10import { INativeEnvironmentService } from '../../../../platform/environment/common/environment.js';11import { ILogService } from '../../../../platform/log/common/log.js';12import { StorageClient } from '../../../../platform/storage/common/storageIpc.js';13import { EXTENSION_DEVELOPMENT_EMPTY_WINDOW_WORKSPACE } from '../../../../platform/workspace/common/workspace.js';14import { NON_EMPTY_WORKSPACE_ID_LENGTH } from '../../../../platform/workspaces/node/workspaces.js';15import { INativeHostService } from '../../../../platform/native/common/native.js';16import { IMainProcessService } from '../../../../platform/ipc/common/mainProcessService.js';17import { Schemas } from '../../../../base/common/network.js';1819export class UnusedWorkspaceStorageDataCleaner extends Disposable {2021constructor(22@INativeEnvironmentService private readonly environmentService: INativeEnvironmentService,23@ILogService private readonly logService: ILogService,24@INativeHostService private readonly nativeHostService: INativeHostService,25@IMainProcessService private readonly mainProcessService: IMainProcessService26) {27super();2829const scheduler = this._register(new RunOnceScheduler(() => {30this.cleanUpStorage();31}, 30 * 1000 /* after 30s */));32scheduler.schedule();33}3435private async cleanUpStorage(): Promise<void> {36this.logService.trace('[storage cleanup]: Starting to clean up workspace storage folders for unused empty workspaces.');3738try {39const workspaceStorageHome = this.environmentService.workspaceStorageHome.with({ scheme: Schemas.file }).fsPath;40const workspaceStorageFolders = await Promises.readdir(workspaceStorageHome);41const storageClient = new StorageClient(this.mainProcessService.getChannel('storage'));4243await Promise.all(workspaceStorageFolders.map(async workspaceStorageFolder => {44const workspaceStoragePath = join(workspaceStorageHome, workspaceStorageFolder);4546if (workspaceStorageFolder.length === NON_EMPTY_WORKSPACE_ID_LENGTH) {47return; // keep workspace storage for folders/workspaces that can be accessed still48}4950if (workspaceStorageFolder === EXTENSION_DEVELOPMENT_EMPTY_WINDOW_WORKSPACE.id) {51return; // keep workspace storage for empty extension development workspaces52}5354const windows = await this.nativeHostService.getWindows({ includeAuxiliaryWindows: false });55if (windows.some(window => window.workspace?.id === workspaceStorageFolder)) {56return; // keep workspace storage for empty workspaces opened as window57}5859const isStorageUsed = await storageClient.isUsed(workspaceStoragePath);60if (isStorageUsed) {61return; // keep workspace storage for empty workspaces that are in use62}6364this.logService.trace(`[storage cleanup]: Deleting workspace storage folder ${workspaceStorageFolder} as it seems to be an unused empty workspace.`);6566await Promises.rm(workspaceStoragePath);67}));68} catch (error) {69onUnexpectedError(error);70}71}72}737475