improve json cache log messages (for #101050)

This commit is contained in:
Martin Aeschlimann 2021-11-29 23:28:42 +01:00
parent 06f34325ad
commit cd34f23699
No known key found for this signature in database
GPG key ID: 2609A01E695523E3
2 changed files with 40 additions and 16 deletions

View file

@ -71,6 +71,7 @@ async function getPackageInfo(context: ExtensionContext): Promise<IPackageInfo>
interface Log {
trace(message: string): void;
isTrace(): boolean;
dispose(): void;
}
@ -88,12 +89,14 @@ function getLog(outputChannel: OutputChannel): Log {
outputChannel.appendLine(message);
}
},
isTrace() {
return trace;
},
dispose: () => configListener.dispose()
};
}
const retryTimeoutInDays = 2; // 2 days
const retryTimeoutInMs = retryTimeoutInDays * 24 * 60 * 60 * 1000;
const retryTimeoutInHours = 2 * 24; // 2 days
async function getSchemaRequestService(context: ExtensionContext, log: Log): Promise<SchemaRequestService> {
let cache: JSONSchemaCache | undefined = undefined;
@ -133,7 +136,7 @@ async function getSchemaRequestService(context: ExtensionContext, log: Log): Pro
log.trace(`[json schema cache] Response: schema ${uri} unchanged etag ${etag}`);
const content = await cache.getSchema(uri, etag);
const content = await cache.getSchema(uri, etag, true);
if (content) {
log.trace(`[json schema cache] Get schema ${uri} etag ${etag} from cache`);
return content;
@ -159,9 +162,12 @@ async function getSchemaRequestService(context: ExtensionContext, log: Log): Pro
return {
getContent: async (uri: string) => {
if (cache && /^https?:\/\/json\.schemastore\.org\//.test(uri)) {
const content = await cache.getSchemaIfAccessedSince(uri, retryTimeoutInMs);
const content = await cache.getSchemaIfUpdatedSince(uri, retryTimeoutInHours);
if (content) {
log.trace(`[json schema cache] Schema ${uri} from cache without request (last accessed less than ${retryTimeoutInDays} days ago)`);
if (log.isTrace()) {
log.trace(`[json schema cache] Schema ${uri} from cache without request (last accessed ${cache.getLastUpdatedInHours(uri)} hours ago)`);
}
return content;
}
}

View file

@ -11,7 +11,7 @@ import { Memento } from 'vscode';
interface CacheEntry {
etag: string;
fileName: string;
accessTime: number;
updateTime: number;
}
interface CacheInfo {
@ -24,18 +24,34 @@ export class JSONSchemaCache {
private readonly cacheInfo: CacheInfo;
constructor(private readonly schemaCacheLocation: string, private readonly globalState: Memento) {
this.cacheInfo = globalState.get<CacheInfo>(MEMENTO_KEY, {});
const infos = globalState.get<CacheInfo>(MEMENTO_KEY, {}) as CacheInfo;
const validated: CacheInfo = {};
for (const schemaUri in infos) {
const { etag, fileName, updateTime } = infos[schemaUri];
if (typeof etag === 'string' && typeof fileName === 'string' && typeof updateTime === 'number') {
validated[schemaUri] = { etag, fileName, updateTime };
}
}
this.cacheInfo = validated;
}
getETag(schemaUri: string): string | undefined {
return this.cacheInfo[schemaUri]?.etag;
}
getLastUpdatedInHours(schemaUri: string): number | undefined {
const updateTime = this.cacheInfo[schemaUri]?.updateTime;
if (updateTime !== undefined) {
return (new Date().getTime() - updateTime) / 1000 / 60 / 60;
}
return undefined;
}
async putSchema(schemaUri: string, etag: string, schemaContent: string): Promise<void> {
try {
const fileName = getCacheFileName(schemaUri);
await fs.writeFile(path.join(this.schemaCacheLocation, fileName), schemaContent);
const entry: CacheEntry = { etag, fileName, accessTime: new Date().getTime() };
const entry: CacheEntry = { etag, fileName, updateTime: new Date().getTime() };
this.cacheInfo[schemaUri] = entry;
} catch (e) {
delete this.cacheInfo[schemaUri];
@ -44,19 +60,19 @@ export class JSONSchemaCache {
}
}
async getSchemaIfAccessedSince(schemaUri: string, expirationDuration: number): Promise<string | undefined> {
const cacheEntry = this.cacheInfo[schemaUri];
if (cacheEntry && cacheEntry.accessTime + expirationDuration >= new Date().getTime()) {
return this.loadSchemaFile(schemaUri, cacheEntry);
async getSchemaIfUpdatedSince(schemaUri: string, expirationDurationInHours: number): Promise<string | undefined> {
const lastUpdatedInHours = this.getLastUpdatedInHours(schemaUri);
if (lastUpdatedInHours !== undefined && (lastUpdatedInHours < expirationDurationInHours)) {
return this.loadSchemaFile(schemaUri, this.cacheInfo[schemaUri], false);
}
return undefined;
}
async getSchema(schemaUri: string, etag: string): Promise<string | undefined> {
async getSchema(schemaUri: string, etag: string, etagValid: boolean): Promise<string | undefined> {
const cacheEntry = this.cacheInfo[schemaUri];
if (cacheEntry) {
if (cacheEntry.etag === etag) {
return this.loadSchemaFile(schemaUri, cacheEntry);
return this.loadSchemaFile(schemaUri, cacheEntry, etagValid);
} else {
this.deleteSchemaFile(schemaUri, cacheEntry);
}
@ -64,11 +80,13 @@ export class JSONSchemaCache {
return undefined;
}
private async loadSchemaFile(schemaUri: string, cacheEntry: CacheEntry): Promise<string | undefined> {
private async loadSchemaFile(schemaUri: string, cacheEntry: CacheEntry, isUpdated: boolean): Promise<string | undefined> {
const cacheLocation = path.join(this.schemaCacheLocation, cacheEntry.fileName);
try {
const content = (await fs.readFile(cacheLocation)).toString();
cacheEntry.accessTime = new Date().getTime();
if (isUpdated) {
cacheEntry.updateTime = new Date().getTime();
}
return content;
} catch (e) {
delete this.cacheInfo[schemaUri];