Path: blob/main/src/vs/workbench/services/configuration/common/configurationCache.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 { IConfigurationCache, ConfigurationKey } from './configuration.js';6import { URI } from '../../../../base/common/uri.js';7import { FileOperationError, FileOperationResult, IFileService } from '../../../../platform/files/common/files.js';8import { joinPath } from '../../../../base/common/resources.js';9import { VSBuffer } from '../../../../base/common/buffer.js';10import { Queue } from '../../../../base/common/async.js';11import { IEnvironmentService } from '../../../../platform/environment/common/environment.js';1213export class ConfigurationCache implements IConfigurationCache {1415private readonly cacheHome: URI;16private readonly cachedConfigurations: Map<string, CachedConfiguration> = new Map<string, CachedConfiguration>();1718constructor(19private readonly donotCacheResourcesWithSchemes: string[],20environmentService: IEnvironmentService,21private readonly fileService: IFileService22) {23this.cacheHome = environmentService.cacheHome;24}2526needsCaching(resource: URI): boolean {27// Cache all non native resources28return !this.donotCacheResourcesWithSchemes.includes(resource.scheme);29}3031read(key: ConfigurationKey): Promise<string> {32return this.getCachedConfiguration(key).read();33}3435write(key: ConfigurationKey, content: string): Promise<void> {36return this.getCachedConfiguration(key).save(content);37}3839remove(key: ConfigurationKey): Promise<void> {40return this.getCachedConfiguration(key).remove();41}4243private getCachedConfiguration({ type, key }: ConfigurationKey): CachedConfiguration {44const k = `${type}:${key}`;45let cachedConfiguration = this.cachedConfigurations.get(k);46if (!cachedConfiguration) {47cachedConfiguration = new CachedConfiguration({ type, key }, this.cacheHome, this.fileService);48this.cachedConfigurations.set(k, cachedConfiguration);49}50return cachedConfiguration;51}52}5354class CachedConfiguration {5556private queue: Queue<void>;57private cachedConfigurationFolderResource: URI;58private cachedConfigurationFileResource: URI;5960constructor(61{ type, key }: ConfigurationKey,62cacheHome: URI,63private readonly fileService: IFileService64) {65this.cachedConfigurationFolderResource = joinPath(cacheHome, 'CachedConfigurations', type, key);66this.cachedConfigurationFileResource = joinPath(this.cachedConfigurationFolderResource, type === 'workspaces' ? 'workspace.json' : 'configuration.json');67this.queue = new Queue<void>();68}6970async read(): Promise<string> {71try {72const content = await this.fileService.readFile(this.cachedConfigurationFileResource);73return content.value.toString();74} catch (e) {75return '';76}77}7879async save(content: string): Promise<void> {80const created = await this.createCachedFolder();81if (created) {82await this.queue.queue(async () => {83await this.fileService.writeFile(this.cachedConfigurationFileResource, VSBuffer.fromString(content));84});85}86}8788async remove(): Promise<void> {89try {90await this.queue.queue(() => this.fileService.del(this.cachedConfigurationFolderResource, { recursive: true, useTrash: false }));91} catch (error) {92if ((<FileOperationError>error).fileOperationResult !== FileOperationResult.FILE_NOT_FOUND) {93throw error;94}95}96}9798private async createCachedFolder(): Promise<boolean> {99if (await this.fileService.exists(this.cachedConfigurationFolderResource)) {100return true;101}102try {103await this.fileService.createFolder(this.cachedConfigurationFolderResource);104return true;105} catch (error) {106return false;107}108}109}110111112113