microsoft / etcd3 Goto Github PK
View Code? Open in Web Editor NEW:bookmark: Node.js client for etcd3
Home Page: https://microsoft.github.io/etcd3/classes/etcd3.html
License: Other
:bookmark: Node.js client for etcd3
Home Page: https://microsoft.github.io/etcd3/classes/etcd3.html
License: Other
Following my conclusion from #61 I saw that when the last watch is canceled, the gRPC stream on the client side is closed, and a new one is created when a new watch is requested.
Looking at the etcd prometheus metric etcd_debugging_mvcc_watch_stream_total, the watch stream in the server is not closed, and the count is increasing until the client process exit.
This leads to resource leak in the server.
I want to synchronous data from etcd to node.js application.
But if I watch the key after getting it, I think the change that occurs during get() and watch() may be lost.
And if I can watch the historical change, the task of synchronizing data will be simply resolved.
And I found the official website of etcd shows an example as follows.
etcdctl watch --rev=2 foo
this command could watch the historical changes.
Or is there any other way can help synchronous data without losing change event.
My code:
const { Etcd3 } = require('etcd3');
const uuidv4 = require('uuid/v4');
const path = `path-${uuidv4()}`;
const client = new Etcd3({ hosts: 'http://localhost:4001' });
let watcher;
const watch = async (path) => {
watcher = await client.watch().prefix(path).create();
}
const unwatch = async () => {
await watcher.cancel();
}
const test = async () => {
await watch(path);
console.log(`success watch`);
await unwatch();
console.log(`success unwatch`);
await watch(path); // this does not resolved
console.log(`success watch`);
}
test();
This test prints:
success watch
success unwatch
I would expect:
success watch
success unwatch
success watch
What I'm doing wrong?
This is handled automatically between multiple hosts within the library and caused issues in production for us (related to grpc/grpc#12506)
from @SimonSchick
TypeError: Cannot read property 'availableAfter' of undefined
at util_1.minBy.r (XXX/node_modules/etcd3/lib/src/shared-pool.js:45:61)
at Object.minBy (XXX/node_modules/etcd3/lib/src/util.js:7:15)
at SharedPool.pull (XXX/node_modules/etcd3/lib/src/shared-pool.js:45:38)
at ConnectionPool.getConnection (XXX/node_modules/etcd3/lib/src/connection-pool.js:132:26)
at ConnectionPool.exec (XXX/node_modules/etcd3/lib/src/connection-pool.js:105:21)
at LeaseClient.leaseGrant (XXX/node_modules/etcd3/lib/src/rpc.js:76:28)
at Lease (XXX/node_modules/etcd3/lib/src/lease.js:52:14)
at Etcd3.lease (XXX/node_modules/etcd3/lib/src/index.js:57:16)
at Discovery.start (XXX/dist/discovery.js:24:46)
at Lease.lease.on.err (XXX/dist/discovery.js:28:18)
at emitOne (events.js:96:13)
at Lease.emit (events.js:188:7)
at Lease.leaseID.client.leaseGrant.then.catch.err (XXX/node_modules/etcd3/lib/src/lease.js:60:18)
var lock = client.lock('foo');
lock.ttl(3); //this will throw an exception "Cannot set a lock TTL after acquiring the lock"
lock.then(...)
solution:
src/lock.ts function ttl(
if (!this.lease) => if(this.lease)
Hey. I'm joining forces today and I'm redirecting my etcd-grpc client to this package because I see that you've already added support for all the available etcd v3
services. That's awesome!
What I would propose is that you add more step-by-step examples and in depth explanation on how things work, because the current documentation isn't always clear and you have to read the source code all the time to really understand what's happening.
I found that my watchers on prefixes were becoming unresponsive but not emitting "disconnected" or "error" or any event for that matter. It's very hard to reproduce but in my testing, I now have one container updating the value of a key on etcd every twenty minutes. I created six containers that each watch with a prefix of that key. Over the course of a few hours, one or two of those containers' watchers will stop seeing the put events.
Have you seen this behavior happen and/or are there suggestions for how to mitigate this or get better logging on why this might be happening?
I noticed this morning that etcd lost the lease used for service discovery on my local instance of our chat server. Chat's last report of the lease being lost and reestablished yesterday. Etcd was empty and when sending SIGINT (which tears down the lease in a graceful shutdown) it errored that the lease was not found in etcd. Seems like it never detected that yesterday's lease was timed out.
{"name":"chat","hostname":"hera.peet.io","pid":18186,"level":30,"err":{"message":"Lease 7587822556486125056 is expired or revoked","name":"Error","stack":"Error: Lease 7587822556486125056 is expired or revoked\n at EtcdLeaseInvalidError (/Users/copeet/Github/chat/node_modules/etcd3/lib/src/errors.js:71:9)\n at ClientDuplexStream.stream.on.res (/Users/copeet/Github/chat/node_modules/etcd3/lib/src/lease.js:158:33)\n at emitOne (events.js:96:13)\n at ClientDuplexStream.emit (events.js:188:7)\n at readableAddChunk (_stream_readable.js:176:18)\n at ClientDuplexStream.Readable.push (_stream_readable.js:134:10)\n at readCallback (/Users/copeet/Github/chat/node_modules/etcd3/node_modules/grpc/src/node/src/client.js:245:14)"},"msg":"Etcd3 lease lost, attempting to re-grant","time":"2017-06-08T17:22:58.238Z","v":0}
{"name":"chat","hostname":"hera.peet.io","pid":18186,"level":30,"msg":"Ectd3 lease re-established","time":"2017-06-08T17:22:58.290Z","v":0}
^CUncaught error: EtcdError: etcdserver: requested lease not found
at /Users/copeet/Github/chat/node_modules/etcd3/node_modules/grpc/src/node/src/client.js:434:17
Uncaught error: EtcdError: etcdserver: requested lease not found
at /Users/copeet/Github/chat/node_modules/etcd3/node_modules/grpc/src/node/src/client.js:434:17
Failed to handle shutdown: EtcdError: etcdserver: requested lease not found
at /Users/copeet/Github/chat/node_modules/etcd3/node_modules/grpc/src/node/src/client.js:434:17
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: `tsc && node dist/index`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/copeet/.npm/_logs/2017-06-09T16_09_43_535Z-debug.log
I'm attempting to read a value from a hosted etcd cluster with a proxy in front (compose.io), but it seems to hang and I'm not really sure what it's doing. I have tested with etcdctl
and it works.
Here's the code I'm using to test. Any ideas?
const { Etcd3 } = require('etcd3') const client = new Etcd3({
hosts: 'https://etcd-proxy.domain.com:1234',
auth: {
username: 'user',
password: 'password'
}
})
console.log("getting...")
client.get('test/test1').string().then(value => {
console.log(value)
})
Hi
I try to use your library to connect etcd but it always fail to do something.
We are using http but we have an authentication with username + password to access it.
When I let the library as it is, I get:
Error: grpc does not allow you to use password authentication without connecting over SSL.
But when I comment the related line in the file connection-pool.js
:
buildAuthentication() {
const { credentials } = this.options;
let protocolCredentials = grpc.credentials.createInsecure();
if (credentials) {
protocolCredentials = grpc.credentials.createSsl(credentials.rootCertificate, credentials.privateKey, credentials.certChain);
}
else if (this.hasSecureHost()) {
protocolCredentials = grpc.credentials.createSsl();
}
// else if (this.options.auth) {
// throw new Error('grpc does not allow you to use password authentication without connecting ' +
// 'over SSL. See how to set up etcd with ssl here: https://git.io/v7uhX');
// }
return this.authenticator.augmentCredentials(protocolCredentials);
}
It does not throw any error AND I can not perform any action with this snippet of code:
const { Etcd3 } = require('etcd3');
const client = new Etcd3({
hosts: 'http://my.domain.com:2379',
auth: {
username: 'my_username',
password: 'my_password'
}
});
client
.get('foo')
.string()
.then(_ => console.log('GOT => ', _))
.catch(err => console.log('ERR => ', err));
It is always waiting for something that didn't come...
If you have any idea how I can do to get a result, it would be very cool !
Thanks
Title says all.
This is my constructor code
const etcd = new Etcd3({
hosts: ['https://example1.com:4758', 'https://example2.com:4758', 'https://example3.com:4758'],
auth: {username: username, password: pwd},
});
And I got this error
GRPCConnectFailedError: Connect Failed\n at /media/zyf/data/Programming/project/duobei/duobeiyun-mobile-server/node_modules/etcd3/node_modules/grpc/src/node/src/client.js:569:15
What happened?
I believe this to be an issue in etcd etcd-io/etcd#8699, opening here for tracking
Is it possible to miss the etcd events, in the event that Watcher.create already occurred, but the event handler is not yet assigned to the watcher?
In code:
const watcher = await etcd.watch().prefix('...').create();
//
// Is there any chance to miss an etcd events in this moment?
//
watcher.on('put', (res) => {
....
});
GRPC allows set request options, for example deadline
.
lib.service.method(requestData, requestOptions, callback);
Please add method addRequestOptions
to your Builders, or create other avaliability for setting request options.
Using [email protected] I'm trying the following:
var etcd = require('etcd3');
var client = new etcd.Etcd3();
var watcher = client.watch().key(new Buffer('/')).create();
I get "TypeError: client.watch is not a function". Am I doing something wrong?
I want to create lease and then update its value every 3-4 minutes..
// create the lease
async createLease(options) {
if (this._lease && !this._lease.revoked()) {
throw new Error('cannot register twice');
}
this._lease = this._client.lease(options.ttl);
this._lease.on('lost', err => {
this.createLease(options);
})
await this.updateLease({ path: options.path, value: options.value });
await this._lease.keepaliveOnce();
}
// I want to call this method when I need to change the value of the lease
async updateLease(options) {
return this._lease.put(options.path).value(JSON.stringify(options.value));
}
Tooling for sharding using etcd would be useful (related: https://github.com/mixer/discord-sync/pull/5)
Hi,
What my use-case is that I want to lock a particular resource from one process and unlock it from another process. Currently, one can lock it like this.
const lock = client.lock('mylock2');
lock.ttl(10).acquire()
.then(lock => {
console.log(lock);
})
.catch(e => console.error("ERROR in aquiring lock, {}", e));
But in order to unlock, one will have use the same lock
object, we wont be possible if I want to unlock it from a different process.
Is there a way to achieve it or can you expose the lease ID so that lock object can be created from the lease ID as well and unlock can be called on that?
I cannot manage to stop node thread when a etcd3's watcher is running. gRPC connection don't seem to be closed and keep thread alive.
Way to reproduce
const {Etcd3} = require('etcd3');
const client = new Etcd3();
const watcher$ = client
.watch()
.prefix('')
.create();
watcher$.then(async watcher => {
console.log('watcher.cancel');
await watcher.cancel();
console.log('client.close');
client.close();
});
# lsof -i tcp:2379 -n -P | grep node
node 35687 arthurweber 13u IPv4 0x181b472d2650f03f 0t0 TCP 127.0.0.1:59146->127.0.0.1:2379 (ESTABLISHED)
This is keenly important to avoid having to use locking. This is trivial to fix in WatchBuilder class by adding something like this to it:
public fromRevision(revision: string, increment: number) {
this.request.start_revision = new BigNumber(revision).add(increment).toString();
return this;
}
The revision I am passing in here is from a previous call to get all of the keys under a prefix. I want to be able to tell it to use that revision plus one (hence the increment). I'm not sure if that is a string or whatnot. I would have done a pull request myself, but I've not dabbled in Typescript, and when I tried to run the tests unmodified they blew up on me.
etcd version: 3.3.5
etcd3: 0.2.11
Server log: etcdserver/api/v3rpc: failed to receive watch request from gRPC stream ("rpc error: code = Canceled desc = context canceled")
How can I fix that bug?
I want to reconnect correctly to etcd cluster, but can't reconnect.
And watcher can't get any event from cluster.
When using '.json()', NaN
is parsed as null
.
my wrapper
import { Etcd3 } from 'etcd3'
import { posix as path } from 'path'
export class EtcdClient<T> {
client: Etcd3
static QUEUE_PREFIX = 'queue'
constructor(protected rootPath: string = '/') {
this.client = new Etcd3({
hosts: [ '127.0.0.1:2379' ]
})
if (!path.isAbsolute(this.rootPath)) {
throw new Error(`the rootPath must be a absolute posix path. but got ${this.rootPath}`)
}
}
protected finalKey(key: string, postfix: string = '') {
return path.join(this.rootPath, key, postfix)
}
async get(key: string): Promise<object|null> {
return await this.client
.get(this.finalKey(key))
.json()
}
async put(key: string, value: T) {
return await this.client
.put(this.finalKey(key))
.value(JSON.stringify(value))
.exec()
}
async destroy() {
this.client.close()
}
}
the test code
import { expect } from 'chai'
import { EtcdClient } from './EtcdClient'
describe.only('', () => {
describe('function', () => {
const key = '__test_key'
const body = {
a: null,
b: NaN,
c: 1,
d: true,
e: 'string',
f: [],
g: {},
h: [1, 2, 3],
i: [null, null],
j: [undefined, undefined],
k: [1, 2],
l: [NaN, NaN],
m: [999999999999999999999999999999999999999, 999999999999999999999999999999999999999],
n: [true, false],
o: ['', ''],
p: ['stringA', 'stringB'],
q: [[], [1]],
}
let client: EtcdClient<typeof body>
beforeEach(async () => {
client = new EtcdClient<typeof body>('/test')
})
afterEach(async () => {
await client.destroy()
})
it('get & set', async () => {
await client.put(key, body)
const resp = await client.get(key)
expect(resp).to.eql(body)
})
})
})
the output
1) function get & set:
AssertionError: expected { Object (a, b, ...) } to deeply equal { Object (a, b, ...) }
+ expected - actual
{
"a": [null]
- "b": [null]
+ "b": NaN
"c": 1
"d": true
"e": "string"
"f": []
[null]
[null]
]
"j": [
- [null]
- [null]
+ [undefined]
+ [undefined]
]
"k": [
1
2
]
"l": [
- [null]
- [null]
+ NaN
+ NaN
]
"m": [
1e+39
1e+39
at Object.<anonymous> (src\crawler\storage\EtcdClient.test.ts:47:29)
at Generator.next (<anonymous>)
at fulfilled (src\crawler\storage\EtcdClient.test.ts:4:58)
at <anonymous>
I checked your code and you forgot to give the metadata to the Watch client
/* rpc#WatchClient */
watch() {
return this.client.getConnection('Watch').then(cnx => cnx.client.watch());
}
Should be
/* rpc#WatchClient */
watch() {
return this.client.getConnection('Watch').then(cnx => cnx.client.watch(cnx.metadata));
}
Same things for LeaseClient#leaseKeepAlive
Getting below error when tried with tls.
E1108 12:08:41.067409000 140736133522368 ssl_transport_security.c:177] ssl_info_callback: error occured.
E1108 12:08:41.087651000 140736133522368 ssl_transport_security.c:921] Handshake failed with fatal error SSL_ERROR_SSL: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure.
(node:17954) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Connect Failed
(node:17954) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
and in etcdserver i'm getting this error for same request
etcdmain: rejected connection from "127.0.0.1:60846" (tls: no cipher suite supported by both client and server)
Same certs/keys worked fine when I tried with golang library https://github.com/coreos/etcd/tree/master/clientv3
Any help would be appreciated
thanks in advance
I noticed that the client.if()
method and some other methods are undefined. In the source code looks like it should work but the npm
package doesn't provide it.
const etcd = new Etcd3();
console.log(etcd.if) // -> undefined
Tried to create client like this:
new Etcd3({ hosts: conf.etcdurl, auth: { username: 'readonly', password: 'readonly' } })
Error is like this:
unexpected error: TypeError: Cannot compose insecure credential
at Object.exports.combineChannelCredentials (/Users/xxx/node_modules/grpc/src/node/src/credentials.js:151:23)
at getCredentialsFromHost.then.token (/Users/xxx/node_modules/etcd3/lib/src/connection-pool.js:62:41)
at <anonymous
Maybe this is related: https://stackoverflow.com/questions/37526077/how-to-add-metadata-to-nodejs-grpc-call
I know in node-etcd (v2) lib that i could use etcd.set(key, value, {ttl: 10}) to set ttl value.
But I did't found anywhere to set ttl value here in etcd3 lib.
WatchManager has potencial bug: etcd does not give guarantees about WatchResponse
(etcd-io/etcd#7036)
https://github.com/mixer/etcd3/blob/05b85c3e4085a0bb00a1c4ff7684935b6b2a1b61/src/lease.ts#L247
Hello, I think logic here is not correct. After lost
is emitted, this.close()
is called and this.state = State.Revoked
is set, so when on('lost')
lease.revoked() === false
.
The put method just provide the put with the key, values as strings. Is there a way to store multiple keys under the single folder to group create/retrieve them ?
Trying to run npm run build:proto
and got error
> [email protected] build:proto /Users/sebastien/Documents/github/mixer
> node ./bin/update-proto ./proto && node bin/generate-methods.js ./proto/rpc.proto > src/rpc.ts
RangeError: Maximum call stack size exceeded
at String.replace (<anonymous>)
at stripPackageNameFrom (/Users/sebastien/Documents/github/mixer/bin/generate-methods.js:98:17)
at MessageCollection.find (/Users/sebastien/Documents/github/mixer/bin/generate-methods.js:63:27)
at _.values.map.f (/Users/sebastien/Documents/github/mixer/bin/generate-methods.js:233:24)
at arrayMap (/Users/sebastien/Documents/github/mixer/node_modules/lodash/lodash.js:660:23)
at Function.map (/Users/sebastien/Documents/github/mixer/node_modules/lodash/lodash.js:9571:14)
at interceptor (/Users/sebastien/Documents/github/mixer/node_modules/lodash/lodash.js:16970:35)
at Function.thru (/Users/sebastien/Documents/github/mixer/node_modules/lodash/lodash.js:8812:14)
at /Users/sebastien/Documents/github/mixer/node_modules/lodash/lodash.js:4379:28
at arrayReduce (/Users/sebastien/Documents/github/mixer/node_modules/lodash/lodash.js:704:21)
at baseWrapperValue (/Users/sebastien/Documents/github/mixer/node_modules/lodash/lodash.js:4378:14)
at LodashWrapper.wrapperValue (/Users/sebastien/Documents/github/mixer/node_modules/lodash/lodash.js:9067:14)
I'm trying to do that because I had to change the file bin/template/duplex-stream-method.tmpl
to allow add metadata when client function are called.
Notes: Even without my changes I got the error
I tried reading our CA cert from a pem formated x509 certificate file and providing to the client in the credentials property of the options argument. I receive a handshake error, SSL_ERROR_SSL: error:14094410:SSL
. I have the same certificate as a .der encoded file, that yields a different error and hangs, Could not load any root certificate
.
Not sure if my cert encoding is off. These same certificate works with other etcd libraries, including the etcd v2 plugin for nconf.
My code is:
const watcher = await etcd.watch().prefix('...').create();
watcher.on('put', (res) => {
console.log('put');
});
watcher.on('delete', (res) => {
console.log('delete');
});
watcher.on('disconnected', () => console.log('disconnected...'));
watcher.on('connected', () => console.log('successfully reconnected!'));
In normal case this code work is correct. After stop and start etcd on console i see this lines:
disconnected...
successfully reconnected!
But the events no longer come.
if (Date.now() - this.lastKeepAlive > 2 * 1000 * this.ttl) {
this.close();
this.emit('lost', new errors_1.GRPCConnectFailedError('We lost connection to etcd and our lease has expired.'));
return;
}
This code is in lease.js keepalive
, and why lost
is fired after twice TTL?
Even if thinking about far past the end of our key's TTL, I think 3s is ok.
The golang client provides an implementation of STM. This API is very useful for applications that update a lot of related keys in parallel.
For example, in my application several administrators can modify the system settings in parallel. However, some settings are related.
Now it has to be implemented manually, because of what the convenience of the API provided by this library is lost (I mean the .json()
method and others)
More information about the topic:
https://coreos.com/blog/transactional-memory-with-etcd3.html
https://godoc.org/github.com/coreos/etcd/clientv3/concurrency#STM
I try use etcd3 v0.2.1. but etcd3 package cannot be installed.
client.patch.js is missing in package?
$ npm i etcd3
> [email protected] install /home/akihiro/test-etcd3/node_modules/grpc
> node-pre-gyp install --fallback-to-build --library=static_library
[grpc] Success: "/home/akihiro/test-etcd3/node_modules/grpc/src/node/extension_binary/grpc_node.node" is installed via remote
> [email protected] install /path/to/node_modules/etcd3
> node client.patch.js
module.js:471
throw err;
^
Error: Cannot find module '/home/akihiro/test-etcd3/node_modules/etcd3/client.patch.js'
at Function.Module._resolveFilename (module.js:469:15)
at Function.Module._load (module.js:417:25)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:393:7)
at startup (bootstrap_node.js:150:9)
at bootstrap_node.js:508:3
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm ERR! Linux 4.9.0-3-amd64
npm ERR! argv "/home/akihiro/.nvm/versions/node/v6.10.1/bin/node" "/home/akihiro/.nvm/versions/node/v6.10.1/bin/npm" "i" "etcd3"
npm ERR! node v6.10.1
npm ERR! npm v3.10.10
npm ERR! code ELIFECYCLE
npm ERR! [email protected] install: `node client.patch.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script 'node client.patch.js'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the etcd3 package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node client.patch.js
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs etcd3
npm ERR! Or if that isn't available, you can get their info via:
npm ERR! npm owner ls etcd3
npm ERR! There is likely additional logging output above.
npm ERR! Please include the following file with any support request:
npm ERR! /home/akihiro/test-etcd3/npm-debug.log
nodejs[20647]: error: main failed: GRPCGenericError: Received message larger than max (10082828 vs. 4194304)
I don't have a good unit test, but the following sequence throws an error:
etcd.getAll().prefix(myPrefix).strings().then()
--> Error: Argument mismatch in makeUnaryRequest
I can dig deeper if needed, but my guess is you just need to fix your dependency for now.
Hello!
It seems like the .get and .watch commands only work for a specific key and not the directory although etcd does have this functionality. Am I missing something in the docs or is this a feature that hasn't been implemented yet? I'd be open to implement it if so!
If you can export types presents inside the file lock.ts
it would be great to for the next release
node_modules/etcd3/lib/src/connection-pool.d.ts(16,98): error TS2694: Namespace '"grpc"' has no exported member 'ChannelOptions'.
node_modules/etcd3/lib/src/options.d.ts(2,10): error TS2305: Module '"grpc"' has no exported member 'ChannelOptions'.
node_modules/etcd3/lib/src/rpc.d.ts(13,43): error TS2694: Namespace '"grpc"' has no exported member 'StatusMessage'.
etcd3: 0.2.7
typescript: 2.6.2
For the cancel watch to work, the watch_id field needs to be saved.
From what I can see, the watch_id is always 0 (the default value?). This causes the cancelWatch gRPC method to always have id 0.
It seems that watchResponse message is too short. It only decodes the messageHeader
I'm not familiar with gRPC so I might be missing something.
Could you take a look?
Thanks
Hi, we're trying to use distributed locking in a project but we're having some trouble getting them to work. Maybe we don't get how they're supposed to work. We have a little test case here that should reproduce the problem:
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/coreos/etcd/clientv3"
"github.com/coreos/etcd/clientv3/concurrency"
)
func main() {
cli, err := clientv3.New(clientv3.Config{Endpoints: []string{"localhost:2379"}})
if err != nil {
log.Fatal(err)
}
defer cli.Close()
// get a grant
ctxc, cancelc := context.WithTimeout(context.Background(), 1*time.Second)
lresp, err := cli.Grant(ctxc, 2)
if err != nil {
log.Fatal(err)
}
defer cancelc()
fmt.Println("lease", lresp.ID)
// create two separate sessions for lock competition
s1, err := concurrency.NewSession(cli, concurrency.WithLease(lresp.ID))
if err != nil {
log.Fatal(err)
}
defer s1.Close()
m1 := concurrency.NewMutex(s1, "/xxxsx/")
s2, err := concurrency.NewSession(cli)
if err != nil {
log.Fatal(err)
}
defer s2.Close()
m2 := concurrency.NewMutex(s2, "/xxxsx/")
// acquire lock for s1
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
if err := m1.Lock(ctx); err != nil {
log.Fatal("timeout", err)
}
defer cancel()
fmt.Println("acquired lock for s1")
m2Locked := make(chan struct{})
go func() {
defer close(m2Locked)
// wait until s1 is unlocked /xxxsx/
if err := m2.Lock(context.TODO()); err != nil {
log.Fatal(err)
}
}()
<-m2Locked
fmt.Println("acquired lock for s2")
}
As you can see, we get a grant with a TTL of 2 seconds :
lresp, err := cli.Grant(ctxc, 2)
And this lease is used when we create the section:
s1, err := concurrency.NewSession(cli, concurrency.WithLease(lresp.ID))
We manage to acquire the lock correctly the first time, but the second Lock
(from a goroutine) never returns.
Shouldn't the lock be unlocked when the lease expires?
After upgrading to Node v10.6.0 - got this message:
(node:32397) DeprecationWarning: grpc.load: Use the @grpc/proto-loader module with grpc.loadPackageDefinition instead.
Everything works fine, but just want let you know
Thanks.
Using v0.2.9, I'm using the same code as in the documentation to acquire a lease:
const lease = client.lease();
https://mixer.github.io/etcd3/classes/lease_.lease.html
But this causes the lease TTL to be undefined which causes an infinite loop for me. Code to reproduce:
const { Etcd3 } = require('etcd3');
const client = new Etcd3({ hosts: 'myhostname:2379' });
const lease = client.lease();
lease.on('lost', err => {
console.log('etcd: lost', err);
});
lease.on('keepaliveFired', () => {
console.log('etcd: keepaliveFired');
});
lease.on('keepaliveSucceeded', () => {
console.log('etcd: keepaliveSucceeded');
});
lease.on('keepaliveFailed', () => {
console.log('etcd: keepaliveFailed');
});
lease.on('keepaliveEstablished', () => {
console.log('etcd: keepaliveEstablished');
});
It does work correctly if I give it a ttl like client.lease(8)
does not cause an issue. But it took me a bit to figure this out, so I wanted to let you know. Maybe clarify documentation?
I've seen this happen twice in in the past several months:
Uncaught error: EtcdError: etcdserver: requested lease not found
at /Users/copeet/Github/chat/node_modules/grpc/src/node/src/client.js:554:15
Uncaught error: EtcdError: etcdserver: requested lease not found
at /Users/copeet/Github/chat/node_modules/grpc/src/node/src/client.js:554:15
Uncaught error: EtcdError: etcdserver: requested lease not found
at /Users/copeet/Github/chat/node_modules/grpc/src/node/src/client.js:554:15
...forever
When I use the client.lease(ttl)
api, it automatically keeps it alive before the TTL ends using an setTimeout
. But what if I do want the leasing to end and automatically revoke all the keys attached to it? I can't find an options to make it happens.
In some cases (code errors, network errors, etc.), the watcher may silently hang. As one of the security tools etcd offers an application level heartbeat based on the progress_notify
parameter when creating a watcher.
Perhaps such a functional would be useful in the library.
As far as I know, this approach is used, at least in libraries, to RabbitMQ to detect network problems.
I created a question to clarify how this option works: etcd-io/etcd#8495
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.