Changelog
1.1.1 2023-07-28
Changelog
1.1.0 2020-11-28
feat: implement elections
Implementation of elections, as seen in etcd's Go client. Elections are most commonly used if you need a single server in charge of a certain task; you run an election on every server where your program is running, and among them they will choose one "leader".
There are two main entrypoints: campaigning via Election.campaign, and observing the leader via Election.observe.
const os = require('os');
const client = new Etcd3();
const election = client.election('singleton-job');
function runCampaign() {
const campaign = election.campaign(os.hostname());
campaign.on('elected', () => {
// This server is now the leader! Let's start doing work
doSomeWork();
});
campaign.on('error', error => {
// An error happened that caused our campaign to fail. If we were the
// leader, make sure to stop doing work (another server is the leader
// now) and create a new campaign.
console.error(error);
stopDoingWork();
setTimeout(runCampaign, 5000);
});
}
async function observeLeader() {
const observer = await election.observe();
console.log('The current leader is', observer.leader());
observer.on('change', leader => console.log('The new leader is', leader));
observer.on('error', () => {
// Something happened that fatally interrupted observation.
setTimeout(observeLeader, 5000);
});
}
Thanks to @yujuiting for their help with the initial implementation. (see #66, #85).
fix: deprecation: watcherBuilder.ignore()
was available for "ignoring" types of events, but it actually did the opposite: it was an include-list, rather than a deny-list. It's deprecated in favor of watchBuilder.only()
fix: buffers not allowed in typings Namespace.get(<key>)
fix: prevent user errors in watcher event listeners from causing backoffs in the underlying stream
Changelog
1.0.2 2020-09-18
fix: update version of cockatiel to fix incompatible TypeScript types (see #128)
fix: don't include the deadline in inherited lease call options (see #131)
feat: allow passing a set of default CallOptions in new Etcd3() (see #133)
When constructing Etcd3
, you can now pass defaultCallOptions
. This can be an object, or a function which will be called for each etcd method call and should return an object. As a function, it will be called with a context object, which looks like:
{
service: 'KV', // etcd service name
method: 'range', // etcd method name
isStream: false, // whether the call create a stream
params: { ... }, // arguments given to the call
}
For example, this will set a 10 second timeout on all calls which are not streams:
const etcd3 = new Etcd3({
defaultCallOptions: context => (context.isStream ? {} : Date.now() + 10000),
});
The default options are shallow merged with any call-specific options. For example this will always result in a 5 second timeout, regardless of what the defaultCallOptions
contains:
etcd3.get('foo').options({ deadline: Date.now() + 5000 });
Changelog
1.0.1 2020-06-21
proto
files not included in npm packageChangelog
1.0.0 2020-06-21
breaking: chore: Node < 10 is no longer supported
breaking: chore: bignumber.js
, used to handle 64-bit numbers returned from etcd, updated from 5.x to 9.0.0
breaking: chore: TypeScript is updated to 3.9, and the types of some function signatures have been narrowed
breaking: chore: grpc has been updated from grpc@1.24
to @grpc/grpc-js@1.0.05
. This affects the optional grpcOptions
that the client can be configured with. The previous package was a couple years old, so you may additionally see different behavior of grpc on your network.
Thank you to @pauliusuza for his help updating everything
breaking: retry
and backoffStrategy
options have been deprecated in favor of a new faultHandling
option.
breaking: GRPCConnectFailedError
has been removed in favor of more accurate, specific GRPC error types.
feat: add faultHandling
option that allows configuring error handling through Cockatiel policies. (see #121)
There are two policies: per-host, and global. Calls will call through the global policy, and then to a host policy. Each time the global policy retries, it will pick a new host to run the call on.
The recommended setup for this is to put a retry policy on the global
slot, and a circuit-breaker policy guarding each host
. Additionally, you can configure a backoff that the watch manager will use for reconnecting watch streams.
By default, global
is set to a three-retry policy and host
is a circuit breaker that will open (stop sending requests) for five seconds after three consecutive failures. The watch backoff defaults to Cockatiel's default exponential options (a max 30 second delay on a decorrelated jitter). If you would like to disable these policies, you can pass Policy.noop
from Cockatiel to the global
and host
options.
Notably, with the default options, you may now receive BrokenCircuitError
s from Cockatiel if calls to a host repeatedly fail.
For example, this is how you would manually specify the default options:
import { Etcd3, isRecoverableError } from 'etcd3';
import { Policy, ConsecutiveBreaker, ExponentialBackoff } from 'cockatiel';
new Etcd3({
faultHandling: {
host: () =>
Policy.handleWhen(isRecoverableError).circuitBreaker(5_000, new ConsecutiveBreaker(3)),
global: Policy.handleWhen(isRecoverableError).retry(3),
watchBackoff: new ExponentialBackoff(),
},
});
Here's how you can disable all fault-handling logic:
import { Etcd3 } from 'etcd3';
import { Policy } from 'cockatiel';
new Etcd3({
faultHandling: {
host: () => Policy.noop,
global: Policy.noop,
},
});
feat: export an isRecoverableError
function that can be used to detect whether the given error is transient, as defined by grpc. Useful when creating retry policies. Recoverable errors will have the exported symbol RecoverableError
as one of their properties.
feat: add SingleRangeBuilder.exists()
that returns if the given key exists
feat: allow apply call options to authentication token exchange (see #111)
feat: allow disabling automatic lease keep-alives (see #110)
fix: errors when creating watchers not being handled correctly (see #114)
fix: mark leases as lost if the watch connection is alive but etcd is unresponsive (see #110)
Changelog
0.2.13 2019-07-03
lease.put
in transactions not applying the lease to the target key (see #92)markFailed
on the mock instance, rather than the real connection pool, whilst mocking (see #94)Changelog
0.2.10 2018-05-05
lease.release()
to let leases expire automatically (see #69)