catalog-backend: add scoped readLocation cache

Co-authored-by: Fredrik Adelöw <freben@gmail.com>
Co-authored-by: blam <ben@blam.sh>
Co-authored-by: Johan Haals <johan.haals@gmail.com>
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2021-09-22 17:35:52 +02:00
committed by Johan Haals
parent 69acb4e7ba
commit b0e1aa7620
3 changed files with 97 additions and 5 deletions
@@ -318,7 +318,7 @@ export class DefaultCatalogProcessingOrchestrator
false,
context.collector.onEmit,
this.options.parser,
context.cache.forProcessor(processor),
context.cache.forProcessor(processor, target),
);
if (read) {
didRead = true;
@@ -75,3 +75,44 @@ describe('ProcessorCacheManager', () => {
).resolves.toBe('my-new-value');
});
});
describe('ScopedProcessorCache', () => {
const myProcessor = new MyProcessor();
it('should forward existing state and collect new state', async () => {
const cache = new ProcessorCacheManager({
'my-processor': { 'scope-1': { 'my-key': 'my-value' } },
});
const scopedCache1 = cache.forProcessor(myProcessor, 'scope-1');
const scopedCache2 = cache.forProcessor(myProcessor, 'scope-2');
// Should be empty to begin with
expect(cache.collect()).toEqual({
'my-processor': { 'scope-1': { 'my-key': 'my-value' } },
});
await scopedCache2.set('my-new-key-2', 'my-new-value-2');
expect(cache.collect()).toEqual({
'my-processor': {
'scope-1': { 'my-key': 'my-value' },
'scope-2': { 'my-new-key-2': 'my-new-value-2' },
},
});
await scopedCache1.set('my-new-key', 'my-new-value');
await expect(scopedCache1.get<string>('my-key')).resolves.toBe('my-value');
await expect(
scopedCache1.get<string>('my-new-key'),
).resolves.toBeUndefined();
expect(cache.collect()).toEqual({
'my-processor': {
'scope-1': { 'my-new-key': 'my-new-value' },
'scope-2': { 'my-new-key-2': 'my-new-value-2' },
},
});
});
});
@@ -19,7 +19,7 @@ import { CatalogProcessor } from '../../ingestion/processors';
import { CatalogProcessorCache } from '../../ingestion/processors/types';
import { isObject } from './util';
class SingleProcessorCache implements CatalogProcessorCache {
class SingleProcessorSubCache implements CatalogProcessorCache {
private newState?: JsonObject;
constructor(private readonly existingState?: JsonObject) {}
@@ -46,17 +46,68 @@ class SingleProcessorCache implements CatalogProcessorCache {
}
}
class SingleProcessorCache implements CatalogProcessorCache {
private newState?: JsonObject;
private subCaches: Map<string, SingleProcessorSubCache> = new Map();
constructor(private readonly existingState?: JsonObject) {}
async get<ItemType extends JsonValue>(
key: string,
): Promise<ItemType | undefined> {
return this.existingState?.[key] as ItemType | undefined;
}
async set<ItemType extends JsonValue>(
key: string,
value: ItemType,
): Promise<void> {
if (!this.newState) {
this.newState = {};
}
this.newState[key] = value;
}
withKey(key: string) {
const existingSubCache = this.subCaches.get(key);
if (existingSubCache) {
return existingSubCache;
}
const existing = this.existingState?.[key];
const subCache = new SingleProcessorSubCache(
isObject(existing) ? existing : undefined,
);
this.subCaches.set(key, subCache);
return subCache;
}
collect(): JsonObject | undefined {
let obj = this.newState ?? this.existingState;
for (const [key, subCache] of this.subCaches) {
const subCacheValue = subCache.collect();
if (subCacheValue) {
obj = { ...obj, [key]: subCacheValue };
}
}
return obj;
}
}
export class ProcessorCacheManager {
private caches = new Map<string, SingleProcessorCache>();
constructor(private readonly existingState: JsonObject) {}
forProcessor(processor: CatalogProcessor): CatalogProcessorCache {
forProcessor(
processor: CatalogProcessor,
key?: string,
): CatalogProcessorCache {
// constructor name will be deprecated in the future when we make `getProcessorName` required in the implementation
const name = processor.getProcessorName?.() ?? processor.constructor.name;
const cache = this.caches.get(name);
if (cache) {
return cache;
return key ? cache.withKey(key) : cache;
}
const existing = this.existingState[name];
@@ -65,7 +116,7 @@ export class ProcessorCacheManager {
isObject(existing) ? existing : undefined,
);
this.caches.set(name, newCache);
return newCache;
return key ? newCache.withKey(key) : newCache;
}
collect(): JsonObject {