-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(PE-6695/PE-6696): remove resolver, add redis support for arns cache #200
Changes from all commits
037417e
3b09c9e
ecb7574
379e027
0041495
f1bd0cf
d114821
410cb5f
b8afa1c
b9e4fe6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,56 +17,90 @@ | |
*/ | ||
import winston from 'winston'; | ||
import { NameResolution, NameResolver } from '../types.js'; | ||
import * as metrics from '../metrics.js'; | ||
import { KvArnsStore } from '../store/kv-arns-store.js'; | ||
|
||
export class CompositeArNSResolver implements NameResolver { | ||
private log: winston.Logger; | ||
private resolvers: NameResolver[]; | ||
private cache: KvArnsStore; | ||
|
||
constructor({ | ||
log, | ||
resolvers, | ||
cache, | ||
}: { | ||
log: winston.Logger; | ||
resolvers: NameResolver[]; | ||
cache: KvArnsStore; | ||
}) { | ||
this.log = log.child({ class: 'CompositeArNSResolver' }); | ||
this.log = log.child({ class: this.constructor.name }); | ||
this.resolvers = resolvers; | ||
this.cache = cache; | ||
} | ||
|
||
async resolve(name: string): Promise<NameResolution> { | ||
this.log.info('Resolving name...', { name }); | ||
let resolution: NameResolution | undefined; | ||
|
||
try { | ||
const cachedResolutionBuffer = await this.cache.get(name); | ||
if (cachedResolutionBuffer) { | ||
const cachedResolution: NameResolution = JSON.parse( | ||
cachedResolutionBuffer.toString(), | ||
); | ||
resolution = cachedResolution; // hold on tho this in case we need it | ||
if ( | ||
cachedResolution !== undefined && | ||
cachedResolution.resolvedAt !== undefined && | ||
cachedResolution.ttl !== undefined && | ||
cachedResolution.resolvedAt + cachedResolution.ttl * 1000 > Date.now() | ||
) { | ||
metrics.arnsCacheHitCounter.inc(); | ||
this.log.info('Cache hit for arns name', { name }); | ||
return cachedResolution; | ||
} | ||
} | ||
metrics.arnsCacheMissCounter.inc(); | ||
this.log.info('Cache miss for arns name', { name }); | ||
|
||
for (const resolver of this.resolvers) { | ||
this.log.debug('Attempting to resolve name with resolver', { | ||
resolver, | ||
}); | ||
const resolution = await resolver.resolve(name); | ||
if (resolution.resolvedId !== undefined) { | ||
return resolution; | ||
try { | ||
this.log.info('Attempting to resolve name with resolver', { | ||
type: resolver.constructor.name, | ||
name, | ||
}); | ||
const resolution = await resolver.resolve(name); | ||
if (resolution.resolvedId !== undefined) { | ||
this.cache.set(name, Buffer.from(JSON.stringify(resolution))); | ||
this.log.info('Resolved name', { name, resolution }); | ||
return resolution; | ||
} | ||
} catch (error: any) { | ||
this.log.error('Error resolving name with resolver', { | ||
resolver, | ||
message: error.message, | ||
stack: error.stack, | ||
}); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we fall back to the cached resolution here, perhaps with some staleness threshold, if we have one? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure, can add that, we can use the TTL of the cache as the staleness threshold. that would mean if the cache has it, and we can't fetch anything new - return what the cache has until it expires. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. modified to return the cached resolution data on error - if we have it - here - b9e4fe6 |
||
this.log.warn('Unable to resolve name against all resolvers', { name }); | ||
return { | ||
name, | ||
resolvedId: undefined, | ||
resolvedAt: undefined, | ||
processId: undefined, | ||
ttl: undefined, | ||
}; | ||
} catch (error: any) { | ||
this.log.error('Error resolving name:', { | ||
name, | ||
message: error.message, | ||
stack: error.stack, | ||
}); | ||
return { | ||
} | ||
// return the resolution if it exists, otherwise return an empty resolution | ||
return ( | ||
resolution ?? { | ||
name, | ||
resolvedId: undefined, | ||
resolvedAt: undefined, | ||
ttl: undefined, | ||
processId: undefined, | ||
}; | ||
} | ||
} | ||
); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👋