Skip to content

Commit

Permalink
Add entry source, either cache or query (#63)
Browse files Browse the repository at this point in the history
  • Loading branch information
monkbroc authored Aug 5, 2022
1 parent 45b18da commit 185a8a4
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 7 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ The timestamp (`Date.now() + ttl * 1000`) when the entry expires.

The time in seconds for its lifetime.

#### source

**Note**: This is not present when falling back to `dns.lookup(...)`!

Whether this entry was loaded from the cache or came from a query (`cache` or `query`)

### Entry object (callback-style)

When `options.all` is `false`, then `callback(error, address, family, expires, ttl)` is called. <br>
Expand Down
5 changes: 5 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {Agent} from 'http';
type AsyncResolver = dnsPromises.Resolver;

export type IPFamily = 4 | 6;
export type EntrySource = 'query' | 'cache';

type TPromise<T> = T | Promise<T>;

Expand Down Expand Up @@ -72,6 +73,10 @@ export interface EntryObject {
* The expiration timestamp.
*/
readonly expires?: number;
/**
* Whether this entry comes from the cache or a query
*/
readonly source?: EntrySource;
}

export interface LookupOptions {
Expand Down
6 changes: 4 additions & 2 deletions source/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ class CacheableLookup {
if (options.all) {
callback(null, result);
} else {
callback(null, result.address, result.family, result.expires, result.ttl);
callback(null, result.address, result.family, result.expires, result.ttl, result.source);
}
}, callback);
}
Expand Down Expand Up @@ -211,6 +211,7 @@ class CacheableLookup {
}

async query(hostname) {
let source = 'cache';
let cached = await this._cache.get(hostname);

if (!cached) {
Expand All @@ -219,6 +220,7 @@ class CacheableLookup {
if (pending) {
cached = await pending;
} else {
source = 'query';
const newPromise = this.queryAndCache(hostname);
this._pending[hostname] = newPromise;

Expand All @@ -231,7 +233,7 @@ class CacheableLookup {
}

cached = cached.map(entry => {
return {...entry};
return {...entry, source};
});

return cached;
Expand Down
21 changes: 16 additions & 5 deletions tests/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ const verify = (t, entry, value) => {
for (const key in value) {
t.true(typeof entry[key].expires === 'number' && entry[key].expires >= Date.now() - 1000);
t.true(typeof entry[key].ttl === 'number' && entry[key].ttl >= 0);
t.true(['cache', 'query'].includes(entry[key].source));

if (!('ttl' in value[key]) && 'ttl' in entry[key]) {
value[key].ttl = entry[key].ttl;
Expand All @@ -245,10 +246,15 @@ const verify = (t, entry, value) => {
if (!('expires' in value[key]) && 'expires' in entry[key]) {
value[key].expires = entry[key].expires;
}

if (!('source' in value[key]) && 'source' in entry[key]) {
value[key].source = entry[key].source;
}
}
} else {
t.true(typeof entry.expires === 'number' && entry.expires >= Date.now() - 1000);
t.true(typeof entry.ttl === 'number' && entry.ttl >= 0);
t.true(['cache', 'query'].includes(entry.source));

if (!('ttl' in value)) {
value.ttl = entry.ttl;
Expand All @@ -257,6 +263,10 @@ const verify = (t, entry, value) => {
if (!('expires' in value)) {
value.expires = entry.expires;
}

if (!('source' in value)) {
value.source = entry.source;
}
}

t.deepEqual(entry, value);
Expand Down Expand Up @@ -401,18 +411,18 @@ test.serial('caching works', async t => {
// Make sure default behavior is right
let entries = await cacheable.lookupAsync('temporary', {all: true, family: 4});
verify(t, entries, [
{address: '127.0.0.1', family: 4}
{address: '127.0.0.1', family: 4, source: 'query'}
]);

// Update DNS data
const resovlerEntry = resolver.data['127.0.0.1'].temporary[0];
const {address: resolverAddress} = resovlerEntry;
resovlerEntry.address = '127.0.0.2';

// Lookup again
// Lookup again returns cached data
entries = await cacheable.lookupAsync('temporary', {all: true, family: 4});
verify(t, entries, [
{address: '127.0.0.1', family: 4}
{address: '127.0.0.1', family: 4, source: 'cache'}
]);

// Restore back
Expand Down Expand Up @@ -486,7 +496,7 @@ test('callback style', async t => {

// Without options
let result = await lookup('localhost');
t.is(result.length, 4);
t.is(result.length, 5);
t.is(result[0], '127.0.0.1');
t.is(result[1], 4);
t.true(typeof result[2] === 'number' && result[2] >= Date.now() - 1000);
Expand Down Expand Up @@ -1038,7 +1048,8 @@ test('slow dns.lookup', async t => {

t.deepEqual(entry, {
address: '127.0.0.1',
family: 4
family: 4,
source: 'query'
});
});

Expand Down

0 comments on commit 185a8a4

Please sign in to comment.