aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: 4bd038e502b5f69ee375891ed1fc69e7332bb877 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# srv-discovery

A small DNS SRV record based service-discovery helper for Node.js.

Most basic usage example:

	const request = require('request-promise-native');
	const { resolve } = require('srv-discovery');

	// Find an hostname and port where the service is listening and then make a
	// HTTP request to it:
	resolve('_myservice._tcp.example.com')
		.then(addr => request(`http://${addr}/path/to/123`))
		.then(res => console.log(res));

Calling `resolve()` the first time performs a DNS query. After that answer is
cached for as long as the TTL field allows. Note that while calling `resolve()`
past TTL triggers a new DNS query `resolve()` might return a cache address
without waiting for the DNS answer. This behavior can be adjusted using the
`maxStale` option.

## Advanced usage

It is possible to configure the behavior of the `resolve()` function by
creating a custom `Agent`:

	const { Agent } = require('srv-discovery');
	const agent = new Agent({
		// Number of seconds, how long past TTL are the cached addresses still
		// good for.
		maxStale: 120,

		// Maximum number of seconds to wait after repeating a failed DNS
		// query.
		maxRetryWait: 30,

		// Maximum number of milliseconds to wait for a DNS answer before
		// timing out.
		resolveTimeoutMs: 1200,

		// List of custom name servers to use. By default the system's
		// nameservers are used.
		nameservers: ['8.8.8.8', '8.8.4.4:53'],
	});

	// Resolve addresses using the agent
	agent.resolve(...);

It is also possible to give feedback when the resolved address turns out to be
a bad one:

	agent.resolveFor('_myservice._tcp.example.com', (addr) => {
		return request(`http://${addr}/path/to/123`);
	}).then((res) => {
		console.log('response: ', res);
	});

In the above example, if the request library rejects with an `ECONNREFUSED`
error then the agent will see it and know not to return that address from
future `resolve()` calls. The address will return back to circulation either
when (a) new addresses are received via DNS, or (b) all addresses have been
marked as "bad".

The behavior of `resolveFor` can be adjusted using various options:

	const opts = {
		// Maximum number of times to repeat operations that failed because of
		a bad address. By default this is set to 0.
		maxRetries: 1,

		// The function accepts an error as its argument and return whether
		// that error was caused by a bad address.
		test: (err) => err.name === 'ECONNREFUSED',
	};

	agent.resolveFor('_myservice._tcp.example.com', opts, (addr) => {
		return request(`http://${addr}/path/to/123`);
	});

## Known issues / features:

- The SRV "weight" and "priority" parameters are not considered.