Skip to content
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

fix: add retries for dnslink #467

Merged
merged 1 commit into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions packages/ipns/src/dnslink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ async function recursiveResolveDnslink (domain: string, depth: number, dns: DNS,
throw new Error('recursion limit exceeded')
}

log('query %s for TXT and CNAME records', domain)
log('query %s for TXT records', domain)
const txtRecordsResponse = await dns.query(domain, {
...options,
types: [
Expand Down Expand Up @@ -76,9 +76,8 @@ async function recursiveResolveDnslink (domain: string, depth: number, dns: DNS,
}
}

// no dnslink records found, try CNAMEs
// see if there is a CNAME delegation
log('no DNSLink records found for %s, falling back to CNAME', domain)

const cnameRecordsResponse = await dns.query(domain, {
...options,
types: [
Expand Down
24 changes: 23 additions & 1 deletion packages/ipns/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@

const DEFAULT_LIFETIME_MS = 24 * HOUR
const DEFAULT_REPUBLISH_INTERVAL_MS = 23 * HOUR
const DEFAULT_DNSLINK_RETRIES = 3

export type PublishProgressEvents =
ProgressEvent<'ipns:publish:start'> |
Expand Down Expand Up @@ -321,6 +322,13 @@
* @default 32
*/
maxRecursiveDepth?: number

/**
* Retry in case of transport error
*
* @default 3
*/
retries?: number
}

export interface RepublishOptions extends AbortOptions, ProgressOptions<RepublishProgressEvents | IPNSRoutingEvents> {
Expand Down Expand Up @@ -424,7 +432,21 @@
}

async resolveDNSLink (domain: string, options: ResolveDNSLinkOptions = {}): Promise<ResolveResult> {
const dnslink = await resolveDNSLink(domain, this.dns, this.log, options)
let dnslink = ''
const retries = options.retries ?? DEFAULT_DNSLINK_RETRIES

for (let i = 0; i < retries; i++) {
try {
dnslink = await resolveDNSLink(domain, this.dns, this.log, options)
break
} catch (err) {
if (i === (retries - 1)) {
throw err
}

Check warning on line 445 in packages/ipns/src/index.ts

View check run for this annotation

Codecov / codecov/patch

packages/ipns/src/index.ts#L444-L445

Added lines #L444 - L445 were not covered by tests

log.error('error resolving %s attempt %d of %d', domain, i + 1, retries, err)
}
}

return this.#resolve(dnslink, options)
}
Expand Down
17 changes: 17 additions & 0 deletions packages/ipns/test/resolve-dnslink.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,23 @@ describe('resolveDNSLink', () => {
expect(result.cid.toString()).to.equal('QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn')
})

it('should retry on failure', async () => {
dns.query.withArgs('foobar.baz')
.rejects(new CodeError('Not found', 'ENODATA'))

dns.query.withArgs('_dnslink.foobar.baz')
.onFirstCall().rejects(new CodeError('Not found', 'ENODATA'))
.onSecondCall().resolves(dnsResponse([{
name: '_dnslink.foobar.baz.',
TTL: 60,
type: RecordType.TXT,
data: 'dnslink=/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn'
}]))

const result = await name.resolveDNSLink('foobar.baz', { nocache: true, offline: true })
expect(result.cid.toString()).to.equal('QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn')
})

it('should handle bad records', async () => {
dns.query.withArgs('_dnslink.foobar.baz').resolves(dnsResponse([{
name: 'foobar.baz.',
Expand Down
Loading