diff --git a/src/config.ts b/src/config.ts index 10be111b..60ed3304 100644 --- a/src/config.ts +++ b/src/config.ts @@ -268,6 +268,15 @@ export const ARNS_CACHE_TTL_SECONDS = +env.varOrDefault( `${60 * 60}`, // 1 hour ); +export const ARNS_RESOLVER_OVERRIDE_TTL_SECONDS_STRING = env.varOrUndefined( + 'ARNS_RESOLVER_OVERRIDE_TTL_SECONDS', +); + +export const ARNS_RESOLVER_OVERRIDE_TTL_SECONDS = + ARNS_RESOLVER_OVERRIDE_TTL_SECONDS_STRING !== undefined + ? +ARNS_RESOLVER_OVERRIDE_TTL_SECONDS_STRING + : undefined; + export const ARNS_CACHE_MAX_KEYS = +env.varOrDefault( 'ARNS_CACHE_MAX_KEYS', '10000', diff --git a/src/init/resolvers.ts b/src/init/resolvers.ts index 778a5181..c13b15fb 100644 --- a/src/init/resolvers.ts +++ b/src/init/resolvers.ts @@ -70,12 +70,16 @@ export const createArNSResolver = ({ resolutionOrder, trustedGatewayUrl, networkProcess, + overrides, }: { log: Logger; cache: KvArnsStore; resolutionOrder: (ArNSResolverType | string)[]; trustedGatewayUrl?: string; networkProcess?: AoIORead; + overrides?: { + ttlSeconds?: number; + }; }): NameResolver => { const resolverMap: Record = { 'on-demand': new OnDemandArNSResolver({ @@ -113,5 +117,6 @@ export const createArNSResolver = ({ log, resolvers, cache, + overrides, }); }; diff --git a/src/resolution/composite-arns-resolver.ts b/src/resolution/composite-arns-resolver.ts index 0bbe48ad..b09d65a1 100644 --- a/src/resolution/composite-arns-resolver.ts +++ b/src/resolution/composite-arns-resolver.ts @@ -24,23 +24,34 @@ export class CompositeArNSResolver implements NameResolver { private log: winston.Logger; private resolvers: NameResolver[]; private cache: KvArnsStore; + private overrides: + | { + ttlSeconds?: number; + // TODO: other overrides like fallback txId if not found in resolution + } + | undefined; constructor({ log, resolvers, cache, + overrides, }: { log: winston.Logger; resolvers: NameResolver[]; cache: KvArnsStore; + overrides?: { + ttlSeconds?: number; + }; }) { this.log = log.child({ class: this.constructor.name }); this.resolvers = resolvers; this.cache = cache; + this.overrides = overrides; } async resolve(name: string): Promise { - this.log.info('Resolving name...', { name }); + this.log.info('Resolving name...', { name, overrides: this.overrides }); let resolution: NameResolution | undefined; try { @@ -50,11 +61,13 @@ export class CompositeArNSResolver implements NameResolver { cachedResolutionBuffer.toString(), ); resolution = cachedResolution; // hold on to this in case we need it + // use the override ttl if it exists, otherwise use the cached resolution ttl + const ttlSeconds = this.overrides?.ttlSeconds ?? cachedResolution.ttl; if ( cachedResolution !== undefined && cachedResolution.resolvedAt !== undefined && - cachedResolution.ttl !== undefined && - cachedResolution.resolvedAt + cachedResolution.ttl * 1000 > Date.now() + ttlSeconds !== undefined && + cachedResolution.resolvedAt + ttlSeconds * 1000 > Date.now() ) { metrics.arnsCacheHitCounter.inc(); this.log.info('Cache hit for arns name', { name }); diff --git a/src/system.ts b/src/system.ts index b06db503..157baed1 100644 --- a/src/system.ts +++ b/src/system.ts @@ -568,6 +568,10 @@ export const nameResolver = createArNSResolver({ resolutionOrder: config.ARNS_RESOLVER_PRIORITY_ORDER, networkProcess: arIO, cache: arnsResolverCache, + overrides: { + ttlSeconds: config.ARNS_RESOLVER_OVERRIDE_TTL_SECONDS, + // TODO: other overrides like fallback txId if not found in resolution + }, }); const webhookEmitter = new WebhookEmitter({