mirror of
https://github.com/Microsoft/vscode
synced 2024-10-04 02:14:06 +00:00
[json] add 'Clear schema cache' command. Fixes #138524
This commit is contained in:
parent
1d4b413018
commit
95a9378519
|
@ -27,7 +27,7 @@ namespace VSCodeContentRequest {
|
|||
}
|
||||
|
||||
namespace SchemaContentChangeNotification {
|
||||
export const type: NotificationType<string> = new NotificationType('json/schemaContent');
|
||||
export const type: NotificationType<string | string[]> = new NotificationType('json/schemaContent');
|
||||
}
|
||||
|
||||
namespace ForceValidateRequest {
|
||||
|
@ -101,6 +101,7 @@ export interface Runtime {
|
|||
|
||||
export interface SchemaRequestService {
|
||||
getContent(uri: string): Promise<string>;
|
||||
clearCache?(): Promise<string[]>;
|
||||
}
|
||||
|
||||
export const languageServerDescription = localize('jsonserver.name', 'JSON Language Server');
|
||||
|
@ -111,7 +112,6 @@ export function startClient(context: ExtensionContext, newLanguageClient: Langua
|
|||
|
||||
let rangeFormatting: Disposable | undefined = undefined;
|
||||
|
||||
|
||||
const documentSelector = ['json', 'jsonc'];
|
||||
|
||||
const schemaResolutionErrorStatusBarItem = window.createStatusBarItem('status.json.resolveError', StatusBarAlignment.Right, 0);
|
||||
|
@ -122,6 +122,16 @@ export function startClient(context: ExtensionContext, newLanguageClient: Langua
|
|||
const fileSchemaErrors = new Map<string, string>();
|
||||
let schemaDownloadEnabled = true;
|
||||
|
||||
let isClientReady = false;
|
||||
|
||||
commands.registerCommand('json.clearCache', async () => {
|
||||
if (isClientReady && runtime.schemaRequests.clearCache) {
|
||||
const cachedSchemas = await runtime.schemaRequests.clearCache();
|
||||
await client.sendNotification(SchemaContentChangeNotification.type, cachedSchemas);
|
||||
}
|
||||
window.showInformationMessage(localize('json.clearCache.completed', "JSON schema cache cleared."));
|
||||
});
|
||||
|
||||
// Options to control the language client
|
||||
const clientOptions: LanguageClientOptions = {
|
||||
// Register the server for json documents
|
||||
|
@ -209,6 +219,8 @@ export function startClient(context: ExtensionContext, newLanguageClient: Langua
|
|||
const disposable = client.start();
|
||||
toDispose.push(disposable);
|
||||
client.onReady().then(() => {
|
||||
isClientReady = true;
|
||||
|
||||
const schemaDocuments: { [uri: string]: boolean } = {};
|
||||
|
||||
// handle content request
|
||||
|
|
|
@ -101,14 +101,23 @@ const retryTimeoutInHours = 2 * 24; // 2 days
|
|||
async function getSchemaRequestService(context: ExtensionContext, log: Log): Promise<SchemaRequestService> {
|
||||
let cache: JSONSchemaCache | undefined = undefined;
|
||||
const globalStorage = context.globalStorageUri;
|
||||
|
||||
let clearCache: (() => Promise<string[]>) | undefined;
|
||||
if (globalStorage.scheme === 'file') {
|
||||
const schemaCacheLocation = path.join(globalStorage.fsPath, 'json-schema-cache');
|
||||
await fs.mkdir(schemaCacheLocation, { recursive: true });
|
||||
|
||||
cache = new JSONSchemaCache(schemaCacheLocation, context.globalState);
|
||||
log.trace(`[json schema cache] initial state: ${JSON.stringify(cache.getCacheInfo(), null, ' ')}`);
|
||||
const schemaCache = new JSONSchemaCache(schemaCacheLocation, context.globalState);
|
||||
log.trace(`[json schema cache] initial state: ${JSON.stringify(schemaCache.getCacheInfo(), null, ' ')}`);
|
||||
cache = schemaCache;
|
||||
clearCache = async () => {
|
||||
const cachedSchemas = await schemaCache.clearCache();
|
||||
log.trace(`[json schema cache] cache cleared. Previously cached schemas: ${cachedSchemas.join(', ')}`);
|
||||
return cachedSchemas;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
const isXHRResponse = (error: any): error is XHRResponse => typeof error?.status === 'number';
|
||||
|
||||
const request = async (uri: string, etag?: string): Promise<string> => {
|
||||
|
@ -172,6 +181,7 @@ async function getSchemaRequestService(context: ExtensionContext, log: Log): Pro
|
|||
}
|
||||
}
|
||||
return request(uri, cache?.getETag(uri));
|
||||
}
|
||||
},
|
||||
clearCache
|
||||
};
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ interface CacheInfo {
|
|||
const MEMENTO_KEY = 'json-schema-cache';
|
||||
|
||||
export class JSONSchemaCache {
|
||||
private readonly cacheInfo: CacheInfo;
|
||||
private cacheInfo: CacheInfo;
|
||||
|
||||
constructor(private readonly schemaCacheLocation: string, private readonly globalState: Memento) {
|
||||
const infos = globalState.get<CacheInfo>(MEMENTO_KEY, {}) as CacheInfo;
|
||||
|
@ -120,6 +120,27 @@ export class JSONSchemaCache {
|
|||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public async clearCache(): Promise<string[]> {
|
||||
const uris = Object.keys(this.cacheInfo);
|
||||
try {
|
||||
const files = await fs.readdir(this.schemaCacheLocation);
|
||||
for (const file of files) {
|
||||
try {
|
||||
await fs.unlink(path.join(this.schemaCacheLocation, file));
|
||||
} catch (_e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore
|
||||
} finally {
|
||||
|
||||
this.cacheInfo = {};
|
||||
await this.updateMemento();
|
||||
}
|
||||
return uris;
|
||||
}
|
||||
}
|
||||
function getCacheFileName(uri: string): string {
|
||||
return `${createHash('MD5').update(uri).digest('hex')}.schema.json`;
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
"icon": "icons/json.png",
|
||||
"activationEvents": [
|
||||
"onLanguage:json",
|
||||
"onLanguage:jsonc"
|
||||
"onLanguage:jsonc",
|
||||
"onCommand:json.clearCache"
|
||||
],
|
||||
"main": "./client/out/node/jsonClientMain",
|
||||
"browser": "./client/dist/browser/jsonClientMain",
|
||||
|
@ -133,7 +134,12 @@
|
|||
"fileMatch": "*.schema.json",
|
||||
"url": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
]
|
||||
],
|
||||
"commands": [{
|
||||
"command": "json.clearCache",
|
||||
"title": "%json.command.clearCache%",
|
||||
"category": "JSON"
|
||||
}]
|
||||
},
|
||||
"dependencies": {
|
||||
"request-light": "^0.5.5",
|
||||
|
|
|
@ -14,5 +14,6 @@
|
|||
"json.clickToRetry": "Click to retry.",
|
||||
"json.maxItemsComputed.desc": "The maximum number of outline symbols and folding regions computed (limited for performance reasons).",
|
||||
"json.maxItemsExceededInformation.desc": "Show notification when exceeding the maximum number of outline symbols and folding regions.",
|
||||
"json.enableSchemaDownload.desc": "When enabled, JSON schemas can be fetched from http and https locations."
|
||||
"json.enableSchemaDownload.desc": "When enabled, JSON schemas can be fetched from http and https locations.",
|
||||
"json.command.clearCache": "Clear schema cache"
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace VSCodeContentRequest {
|
|||
}
|
||||
|
||||
namespace SchemaContentChangeNotification {
|
||||
export const type: NotificationType<string> = new NotificationType('json/schemaContent');
|
||||
export const type: NotificationType<string | string[]> = new NotificationType('json/schemaContent');
|
||||
}
|
||||
|
||||
namespace ResultLimitReachedNotification {
|
||||
|
@ -264,8 +264,18 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
|||
});
|
||||
|
||||
// A schema has changed
|
||||
connection.onNotification(SchemaContentChangeNotification.type, uri => {
|
||||
if (languageService.resetSchema(uri)) {
|
||||
connection.onNotification(SchemaContentChangeNotification.type, uriOrUris => {
|
||||
let needsRevalidation = false;
|
||||
if (Array.isArray(uriOrUris)) {
|
||||
for (const uri of uriOrUris) {
|
||||
if (languageService.resetSchema(uri)) {
|
||||
needsRevalidation = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
needsRevalidation = languageService.resetSchema(uriOrUris);
|
||||
}
|
||||
if (needsRevalidation) {
|
||||
for (const doc of documents.all()) {
|
||||
triggerValidation(doc);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue