Cancel cache read if it takes too long
Signed-off-by: Joe Porpeglia <josephp@spotify.com>
This commit is contained in:
committed by
Joe Porpeglia
parent
f5598677bf
commit
413c9fab08
@@ -130,4 +130,19 @@ describe('CachedEntityLoader', () => {
|
||||
ttl: 5000,
|
||||
});
|
||||
});
|
||||
|
||||
it('calls the catalog if the cache read takes too long', async () => {
|
||||
identity.authenticate.mockResolvedValue(identityResponse);
|
||||
cache.get.mockImplementation(
|
||||
() =>
|
||||
new Promise(resolve => {
|
||||
setTimeout(() => resolve(undefined), 10000);
|
||||
}),
|
||||
);
|
||||
catalog.getEntityByName.mockResolvedValue(entity);
|
||||
|
||||
const result = await loader.load(entityName, token);
|
||||
|
||||
expect(result).toEqual(entity);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -30,9 +30,10 @@ export type CachedEntityLoaderOptions = {
|
||||
};
|
||||
|
||||
export class CachedEntityLoader {
|
||||
private catalog: CatalogClient;
|
||||
private cache: CacheClient;
|
||||
private identity: IdentityClient;
|
||||
private readonly catalog: CatalogClient;
|
||||
private readonly cache: CacheClient;
|
||||
private readonly identity: IdentityClient;
|
||||
private readonly readTimeout = 1000;
|
||||
|
||||
constructor({ catalog, cache, identity }: CachedEntityLoaderOptions) {
|
||||
this.catalog = catalog;
|
||||
@@ -45,7 +46,7 @@ export class CachedEntityLoader {
|
||||
token: string | undefined,
|
||||
): Promise<Entity | undefined> {
|
||||
const cacheKey = await this.getCacheKey(entityName, token);
|
||||
let result = (await this.cache.get(cacheKey)) as Entity | undefined;
|
||||
let result = await this.getFromCache(cacheKey);
|
||||
|
||||
if (result) {
|
||||
return result;
|
||||
@@ -68,6 +69,15 @@ export class CachedEntityLoader {
|
||||
return result;
|
||||
}
|
||||
|
||||
private async getFromCache(key: string): Promise<Entity | undefined> {
|
||||
// Promise.race ensures we don't hang the client for long if the cache is
|
||||
// temporarily unreachable.
|
||||
return (await Promise.race([
|
||||
this.cache.get(key),
|
||||
new Promise(cancelAfter => setTimeout(cancelAfter, this.readTimeout)),
|
||||
])) as Entity | undefined;
|
||||
}
|
||||
|
||||
private async getCacheKey(
|
||||
entityName: EntityName,
|
||||
token: string | undefined,
|
||||
|
||||
Reference in New Issue
Block a user