jurmous / etcd4j Goto Github PK
View Code? Open in Web Editor NEWJava / Netty client for etcd, the highly-available key value store for shared configuration and service discovery.
License: Apache License 2.0
Java / Netty client for etcd, the highly-available key value store for shared configuration and service discovery.
License: Apache License 2.0
For example I want to throw custom EtcdException and I can't. Other reason is that i handle IOException, TimeoutException and I want to throw new EtcdException with custom error message. Thus where I use the method which uses the client I will have to handle only single EtcdException, not all of them.
What do you think about that guys?
If a large value is stored etcd4j does not handle it correctly. By large I mean value grater than 8096 which causes io.netty.handler.codec.http.multipart.HttpPostRequestEncoder to create a chunked request. If that happens request without a body is sent to etcd and operation never completes.
Hi there,
Currently prevExist() in EtcdKeyPutRequest can only set prevExist =true. While in certain situations, we would like to have prevExist=false as the condition to set up etcd key. Can you please extend the api to support?
public EtcdKeyPutRequest prevExist() {
this.requestParams.put("prevExist", "true");
return this;
}
Defaulting the Host
header to the local interfaces host name may not be the best default. When connecting to Etcd behind a proxy, the host header needs to match the host being contacted, otherwise the proxy will fail.
A better default would be to extract the host from the url being connected to. This would allow proxies to work as expected.
Hi there,
Seems etcd4j logs a WARN message for each redirect. This results in excessive log messages in clustering environment. It is not really a warning situation.
Here is the message:
Jan 05 2015 15:34:41.339 [nioEventLoopGroup-6-6] [EtcdKeyResponseHandler.java:82] WARN m.e.t.EtcdKeyResponseHandler - redirect for /v2/keys/test to http://127.0.0.1:4004/v2/keys/test
Can you please change the log level to DEBUG or no log at all for this?
Thanks,
Ken
etcd version: 2.3.1
etcd4j version: 2.10.0
description: There are 3 nodes in etcd cluster, I created a EtcdClient, then try to set value, then shut down the EtcdClient. The Thread can be finished.
But if one of the the 3 nodes in the cluster is down, the thread can not be finished, it will be always running.
Code:
EtcdClient etcd = new EtcdClient(
URI.create("http://node1:2379")
,URI.create("http://node2:2379")
,URI.create("http://node3:2379")
);
try {
EtcdKeysResponse response = etcd.put("java", "hi2").timeout(1, TimeUnit.SECONDS).send().get();
System.out.println(response.node.value);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (EtcdException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (EtcdAuthenticationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
etcd.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
The Host name reported by the etcd client should be the cname of the web app. Since Netty gathers the information from resolving the ip with /etc/hosts it should be possible to configure the value if the user wants it to be different.
I use aggressive timeouts when querying ETCD. It often results to timeout exception.
Etcdj4 uses nice system of retry handlers.
However, according to https://github.com/jurmous/etcd4j/blob/master/src/main/java/mousio/etcd4j/transport/EtcdNettyClient.java#L167 it seems that some retry policy is performed only when promise does not succeed. Log entry in the condition says that this happen only when connection failed.
I'd appreciate to use retry handler even for timeout exception. In general, we can say that there are certain conditions when it makes sense to retry but there are also conditions when it does not make a sense to do retry. Depends on a use-case.
From my point of PUT view, I will do retries in case of timeout exception until some counter exceeds or until ETCD results precondition fails - which means that the code changes the value in ETCD but the request was timeout on client side - in fact, it succeeded but after my timeout.
This sounds exactly like an implementation of already implemented handler(s) but placed on request execution itself, not only on connection.
Hi @jurmous ,
as the number of decoders is growing and write them is just a very manual task, would you mind if I switch to Jackson Object Mapper ? I know we already had this discussion but now that the messages we support is growing I think the advantages outcome the small issues it adds (dependencies, maybe slower parsing)
@jurmous if you have time, can you do a new release ?
Sorry for posting this here but i have the following problem.
I create single get request.
try{
EtcdClient client = new EtcdClient(URI.create("http://x.x.x.x:4012"));
EtcdKeysResponse response = client.put("foo", "bar").send().get();
// Prints out: bar
System.out.println(response.node.value);
}catch(EtcdException e){
// Do something with the exception returned by etcd
}catch(IOException e){
// Exception happened in the retrieval. Do something with it.
}catch(TimeoutException e){
// Timeout happened. Do something
}
and there is a thrown exception
WARNING: An exception was thrown by ousio.etcd4j.transport.EtcdNettyClient$3.operationComplete()
java.io.IOException:io.netty.handler.codec.http.multipart.HttpPostRequestEncoder$ErrorDataEncoderException: Cannot create a Encoder if not a POST
at mousio.etcd4j.transport.EtcdNettyClient.createHttpRequest(EtcdNettyClient.java:276)
at mousio.etcd4j.transport.EtcdNettyClient$3.operationComplete(EtcdNettyClient.java:198)
at mousio.etcd4j.transport.EtcdNettyClient$3.operationComplete(EtcdNettyClient.java:159)
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:680)
at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:603)
at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:563)
at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:406)
at io.netty.channel.DefaultChannelPromise.trySuccess(DefaultChannelPromise.java:82)
at >io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.fulfillConnectPromise(AbstractNioChannel.java:247)
at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:282)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:528)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
at java.lang.Thread.run(Thread.java:744)
I implemented PUT/DELETE /v2/auth/enable ,but EtcdResponseHandler.channelRead0 can not handler "status.equals(HttpResponseStatus.OK) && !content.isReadable()" . because auth/enable not response any content.
Hi,
we just noticed that the released etcd4j-0.4.9.jar contains the client classes twice, with different file dates. I can not reproduce building such a file with "gradle jar", I think a gradle clean should fix this problem...?
Greetings, Marc
$ unzip -l etcd4j-0.4.9.jar
Archive: etcd4j-0.4.9.jar
Length Date Time Name
0 10-07-14 13:45 META-INF/
25 10-07-14 13:45 META-INF/MANIFEST.MF
0 10-07-14 13:34 mousio/
0 10-07-14 13:34 mousio/client/
453 10-07-14 13:34 mousio/client/ConnectionState.class
0 10-07-14 13:34 mousio/client/exceptions/
426 10-07-14 13:34 mousio/client/exceptions/PrematureDisconnectException.class
0 10-07-14 13:34 mousio/client/promises/
1541 10-07-14 13:34 mousio/client/promises/ResponsePromise$1.class
912 10-07-14 13:34 mousio/client/promises/ResponsePromise$2.class
462 10-07-14 13:34 mousio/client/promises/ResponsePromise$IsSimplePromiseResponseHandler.class
6025 10-07-14 13:34 mousio/client/promises/ResponsePromise.class
0 10-07-14 13:34 mousio/client/retry/
195 10-07-14 13:34 mousio/client/retry/ConnectionFailHandler.class
197 10-07-14 13:34 mousio/client/retry/RetryHandler.class
680 10-07-14 13:34 mousio/client/retry/RetryNTimes.class
613 10-07-14 13:34 mousio/client/retry/RetryOnce.class
1242 10-07-14 13:34 mousio/client/retry/RetryPolicy$1.class
2336 10-07-14 13:34 mousio/client/retry/RetryPolicy.class
1151 10-07-14 13:34 mousio/client/retry/RetryWithExponentialBackOff.class
911 10-07-14 13:34 mousio/client/retry/RetryWithTimeout.class
0 10-07-14 13:35 mousio/etcd4j/
3795 10-07-14 13:35 mousio/etcd4j/EtcdClient.class
0 10-07-14 13:35 mousio/etcd4j/promises/
1478 10-07-14 13:35 mousio/etcd4j/promises/EtcdResponsePromise.class
0 10-07-14 13:35 mousio/etcd4j/requests/
2773 10-07-14 13:35 mousio/etcd4j/requests/EtcdKeyDeleteRequest.class
3085 10-07-14 13:35 mousio/etcd4j/requests/EtcdKeyGetRequest.class
2685 10-07-14 13:35 mousio/etcd4j/requests/EtcdKeyPostRequest.class
3229 10-07-14 13:35 mousio/etcd4j/requests/EtcdKeyPutRequest.class
2388 10-07-14 13:35 mousio/etcd4j/requests/EtcdKeyRequest.class
3450 10-07-14 13:35 mousio/etcd4j/requests/EtcdRequest.class
1716 10-07-14 13:35 mousio/etcd4j/requests/EtcdVersionRequest.class
0 10-07-14 13:35 mousio/etcd4j/responses/
1310 10-07-14 13:35 mousio/etcd4j/responses/EtcdException.class
1386 10-07-14 13:35 mousio/etcd4j/responses/EtcdKeyAction.class
762 10-07-14 13:35 mousio/etcd4j/responses/EtcdKeysResponse$EtcdNode.class
890 10-07-14 13:35 mousio/etcd4j/responses/EtcdKeysResponse.class
6576 10-07-14 13:35 mousio/etcd4j/responses/EtcdKeysResponseParser.class
0 10-07-14 13:35 mousio/etcd4j/transport/
465 10-07-14 13:35 mousio/etcd4j/transport/EtcdClientImpl.class
4868 10-07-14 13:35 mousio/etcd4j/transport/EtcdKeyResponseHandler.class
2117 10-07-14 13:35 mousio/etcd4j/transport/EtcdNettyClient$1.class
1142 10-07-14 13:35 mousio/etcd4j/transport/EtcdNettyClient$2.class
3029 10-07-14 13:35 mousio/etcd4j/transport/EtcdNettyClient$3.class
2114 10-07-14 13:35 mousio/etcd4j/transport/EtcdNettyClient$4.class
1440 10-07-14 13:35 mousio/etcd4j/transport/EtcdNettyClient$5.class
11217 10-07-14 13:35 mousio/etcd4j/transport/EtcdNettyClient.class
453 10-02-14 11:27 mousio/client/ConnectionState.class
426 10-02-14 11:27 mousio/client/exceptions/PrematureDisconnectException.class
1541 10-02-14 11:27 mousio/client/promises/ResponsePromise$1.class
912 10-02-14 11:27 mousio/client/promises/ResponsePromise$2.class
462 10-02-14 11:27 mousio/client/promises/ResponsePromise$IsSimplePromiseResponseHandler.class
6025 10-02-14 11:27 mousio/client/promises/ResponsePromise.class
195 10-02-14 11:27 mousio/client/retry/ConnectionFailHandler.class
197 10-02-14 11:27 mousio/client/retry/RetryHandler.class
680 10-02-14 11:27 mousio/client/retry/RetryNTimes.class
613 10-02-14 11:27 mousio/client/retry/RetryOnce.class
1242 10-02-14 11:27 mousio/client/retry/RetryPolicy$1.class
2336 10-02-14 11:27 mousio/client/retry/RetryPolicy.class
1151 10-02-14 11:27 mousio/client/retry/RetryWithExponentialBackOff.class
911 10-02-14 11:27 mousio/client/retry/RetryWithTimeout.class
96228 62 files
Hi,
I'm wondering if it would be better to use Long instead of Integer for createdIndex, modifiedIndex and etcdIndex in EtcdKeysResponse / EtcdNode. I think long running and heavily used etcd instances can reach very high values. Maybe Long makes also sense for ttl.
Greetings, Marc
Following call client.getAll().timeout(30, TimeUnit.SECONDS).send().get()
throws NPE because of null key parameter.
java.lang.NullPointerException
at mousio.etcd4j.requests.EtcdKeyRequest.(EtcdKeyRequest.java:60)
at mousio.etcd4j.requests.EtcdKeyRequest.(EtcdKeyRequest.java:46)
at mousio.etcd4j.requests.EtcdKeyGetRequest.(EtcdKeyGetRequest.java:37)
at mousio.etcd4j.EtcdClient.getAll(EtcdClient.java:256)
at
I used version 2.10.0 from maven central.
I have an etcd instance running which is exposed via an nginx reverse-proxy. When I used your client it was failing with a 400 error. When I looked into it, the error reported by nginx was:
client sent HTTP/1.1 request without "Host" header while reading client request headers
I had a look through your code, and did a quick fix to set the host header - see below patch. This seems to have fixed it for me, so I thought you might want to consider incorporating the fix into your next release?
Patch:
diff --git a/src/main/java/mousio/etcd4j/transport/EtcdNettyClient.java b/src/main/java/mousio/etcd4j/transport/EtcdNettyClient.java
index 3c0ef14..0408b00 100644
--- a/src/main/java/mousio/etcd4j/transport/EtcdNettyClient.java
+++ b/src/main/java/mousio/etcd4j/transport/EtcdNettyClient.java
@@ -24,6 +24,7 @@
import org.slf4j.LoggerFactory;
import java.io.IOException;
+import java.net.InetAddress;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.Date;
@@ -258,6 +259,7 @@
public static <R> HttpRequest createHttpRequest(String uri, EtcdRequest<R> etcdRequest) throws IOException {
HttpRequest httpRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_1, etcdRequest.getMethod(), uri);
httpRequest.headers().add("Connection", "keep-alive");
+ httpRequest.headers().add("Host", InetAddress.getLocalHost().getHostName());
try {
httpRequest = setRequestParameters(uri, etcdRequest, httpRequest);
} catch (Exception e) {
Hi,
I noticed that put request with a space in the value return a 400 "bad request". PR follows...
Greetings and happy holidays :)
Since version 2.3 of etcd Time-to-Live (TTL) keys can be refreshed without notifying watchers.
The etcd4j client should support this feature.
I'm running a local etcd v 4.6.
I have a test program that uses waitForChange, and all works well as long as the etcd connection is alive. However if I bounce etcd there is no reconnect. Should there be? Below is my test code.
public class Test {
public static void main(String[] args) throws IOException {
new Thread(new Runnable() {
@Override
public void run() {
final Object lock = this;
while (true) {
System.out.println("waiting");
try (EtcdClient etcd = new EtcdClient(
URI.create("http://127.0.0.1:4001"))) {
EtcdResponsePromise<EtcdKeysResponse> promise = etcd
.get("foo").waitForChange().send();
promise.addListener(r -> {
System.out.println("change!");
try {
System.out.println(r.get().node.value);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (lock) {
lock.notify();
}
});
synchronized (this) {
wait();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
try {
Thread.sleep(10000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Hi,
we would like to use your etcd4j client, but can not switch to Java 8 for our project yet. I had a look at what Java 8 features are used, and it seems it's very little until now. I already changed the code to make it Java 7 compatible, please have a look at https://github.com/slintes/etcd4j/commit/415371143cf4fe026d0110d40add338ca7ecb116
What do you think about keeping your client Java 7 compatible? If you like the idea, I would like to create a pull request.
Kind regards,
Marc
I'm getting some SocketException
s sporadically when developing on my Mac. I can pretty reliably reproduce the issue with the following test (was testing other properties, but ended up finding this fun one)
@Test public void testSharedClient() throws Exception{
EtcdClient client = new EtcdClient(
URI.create("http://127.0.0.1:12379"),
URI.create("http://127.0.0.1:22379"),
URI.create("http://127.0.0.1:32379")
);
for (int i = 0; i < 10_000; i++) {
Thread t = new Thread(() -> {
try {
client.put("test", "test").ttl(3600).send().get();
client.get("test").send().get();
} catch (Exception e) {
e.printStackTrace();
}
});
t.start();
client.put("test-2", "test-2").ttl(3600).send().get();
t.join();
}
}
It seems it may be related to IPv6 based on the literature I can find online for this error and it does seem to be resolved by adding the following system-property.
-Djava.net.preferIPv4Stack=true
Just thought this might be worth adding to the readme as a note / caveat / warning.
Exceptions are currently not caught by pipeline causing a wrapped warning exception which is not clear what the real problem is.
See #1
I use default retry handler RetryWithExponentialBackOff using -1 as maxRetryCount. Unfortunately this specific setting results into infinite loop as method RetryWithExponentialBackOff.shouldRetry returns always true in the case of maxRetryCount=-1 - first condition is always skipped.
Note that I used following statement to create the policy:
new RetryWithExponentialBackOff(20, -1, 1000)
I have a simple etcd4j based application which uses the wait facility to wait on Etcd key changes. When shutting down the application (EtcdClient.close() is called from within proto.close()) the Netty won't shutdown cleanly, even if I take care to explicitly cancel all promises beforehand.
It appears that EtcdClient is not trying hard enough to shutdown the underlying Netty factories or whatever.
proto.close()
[main] INFO mousio.etcd4j.transport.EtcdNettyClient - Shutting down Etcd4j Netty client
after proto.close()
[pool-1-thread-1] WARN io.netty.util.HashedWheelTimer - An exception was thrown by TimerTask.
java.lang.IllegalStateException: executor not accepting a task
at io.netty.resolver.NameResolverGroup.getResolver(NameResolverGroup.java:58)
at io.netty.bootstrap.Bootstrap.doResolveAndConnect(Bootstrap.java:164)
at io.netty.bootstrap.Bootstrap.connect(Bootstrap.java:139)
at io.netty.bootstrap.Bootstrap.connect(Bootstrap.java:120)
.... 10 pages of the usual Netty dung omitted
When I execute etcdClient.getStoreStats() - thread hangs and nothing is returned. Other requests work fine. My setup: etcd4j-2.10.0, Java 1.8_45
I noticed that some threads are not closed with the ARM block. I didn't spend a lot of time figuring out where the threads are kept open, but I was able to write a very simple test and reproduce the issue on my Mac. You may need to adjust the loop counter to whatever your ulimit
value is on your machine.
@Test public void testEtcdClientClosing() throws IOException {
for (int i = 0; i < 10_000; i++) {
try(EtcdClient client = new EtcdClient()) {
client.put("test-" + i, "value-" + i).send();
client.get("test-" + i).send();
} // should close automatically
}
}
Without fail this blows up with an OutOfMemoryError: unable to create new native thread
.
Currently the framework throws an exception when connection closes on a wait. It is possibly better to build in some default Retry Policies.
Some inspiration:
http://curator.apache.org/apidocs/org/apache/curator/RetryPolicy.html
See #3
Hi @jurmous, Im sorry if this is the wrong place for this but I didnt find a room on gitter.
Is it possible to perform GET requests on non /v2/keys
keys? I need to GET /v2/stats/self
and I cant seem to figure out how to do that with etcd4j
I'd appreciate any pointers. Thanks a lot!
Because the netty dependency is attached to the client artifact and gradle maven plugin by default does not include dependencies of the extra artifacts in the generated pom, the Netty dependencies are missing from the pom.
Adapt the gradle build file so it includes the Netty Dependencies.
Etcd allows to bootstrap over SRV records and tools such as confd supports reading them. Would be nice if etcd4j could read them. This is the code that I am using the bootstrap etcd4j using SRV records (I can make a PR if you want to).
https://github.com/coreos/etcd/blob/master/Documentation/clustering.md#dns-discovery
Does this sound like a good idea?
private URI[] getUris(String service) throws NamingException {
List<URI> uris = new ArrayList<>();
String srvService = "_etcd._tcp." + service;
Hashtable<String, String> env = new Hashtable<>();
env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
env.put("java.naming.provider.url", "dns:");
DirContext ctx = new InitialDirContext(env);
Attributes attributes = ctx.getAttributes(srvService, new String[]{"SRV"});
NamingEnumeration<? extends Attribute> records = attributes.getAll();
while (records.hasMore()) {
Attribute next = records.next();
NamingEnumeration<String> values = (NamingEnumeration<String>) next.getAll();
while (values.hasMore()) {
String dns = values.next();
String[] split = dns.split(" ");
String port = split[2];
String host = split[3];
URI uri = URI.create("http://" + host + ":" + port);
uris.add(uri);
}
}
return uris.toArray(new URI[0]);
}
While trying to upgrade from 2.7.0 to 2.9.0, I am seeing lots of ArrayIndexOutOfBoundsException
s being thrown, relating to the uriIndex
field of ConnectionState
. The code in RetryPolicy
is incrementing this field and then testing if the new value is valid. This seems to be causing other threads to use an illegal value when doing lookups in the uris
array. Synchronizing access to the ConnectionState instance seems to resolve the issue.
While testing #15 I noticed that redirects are broken after rebasing on master (508040f). Reproducable without an etcd cluster if you remove the fix for leading slashes (#14) and use a key with leading slash. I get a CancellationException before the request ends successfully.
Log:
[nioEventLoopGroup-2-2] INFO mousio.etcd4j.transport.EtcdNettyClient - Connected to /172.17.8.20:4001
[nioEventLoopGroup-2-2] INFO mousio.etcd4j.transport.EtcdKeyResponseHandler - Received 301 for PUT /v2/keys//etcd4jTest
[nioEventLoopGroup-2-2] INFO mousio.etcd4j.transport.EtcdNettyClient - Connection closed for request PUT /v2/keys//etcd4jTest
[nioEventLoopGroup-2-2] WARN mousio.etcd4j.transport.EtcdKeyResponseHandler - redirect for /v2/keys//etcd4jTest?value=HelloFromEtcd4J to /v2/keys/etcd4jTest?value=HelloFromEtcd4J
[nioEventLoopGroup-2-3] INFO mousio.etcd4j.transport.EtcdNettyClient - Connected to /172.17.8.20:4001
java.io.IOException: java.util.concurrent.CancellationException
at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:55)
at etcdTest.Etcd4JTest.main(Etcd4JTest.java:29)
Caused by: java.util.concurrent.CancellationException
[nioEventLoopGroup-2-3] INFO mousio.etcd4j.transport.EtcdKeyResponseHandler - Received 201 for PUT /v2/keys//etcd4jTest
[nioEventLoopGroup-2-3] INFO mousio.etcd4j.transport.EtcdNettyClient - Connection closed for request PUT /v2/keys//etcd4jTest
Hi,
I'm playing with etcd4j using a sample piece of code below. What I'm seeing, and what I am unable to fix, is the onResponse
handler being invoked twice for each change of /mykey
. Each invocation of the handler seems to happen on a different thread.
I guess it must be related to invoking waitForChange()
from inside the handler itself? What's the proper way to do it?
package testpackage;
import mousio.client.promises.ResponsePromise;
import mousio.etcd4j.EtcdClient;
import mousio.etcd4j.promises.EtcdResponsePromise;
import mousio.etcd4j.responses.EtcdAuthenticationException;
import mousio.etcd4j.responses.EtcdException;
import mousio.etcd4j.responses.EtcdKeysResponse;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.TimeoutException;
public class Main {
public static void main(String[] args) throws URISyntaxException, IOException, EtcdAuthenticationException, TimeoutException, EtcdException, InterruptedException {
EtcdClient client = new EtcdClient(new URI("https://localhost:2379"));
EtcdResponsePromise promise = client.get("/mykey").waitForChange().send();
promise.addListener(new ResponsePromise.IsSimplePromiseResponseHandler() {
@Override
public void onResponse(ResponsePromise responsePromise) {
try {
EtcdKeysResponse response = (EtcdKeysResponse) responsePromise.get();
System.out.println("Waited for: " + response.node.value);
EtcdResponsePromise next = client.get("/mykey").waitForChange(response.etcdIndex + 1).send();
next.addListener(this);
} catch (Exception e) {
e.printStackTrace();
}
}
});
while(true) {
Thread.sleep(1000);
}
}
}
A response like this:
HTTP/1.1 400 Bad Request
Content-Type: application/json
X-Etcd-Cluster-Id: 7e27652122e8b2ae
X-Etcd-Index: 4429
Date: Tue, 05 Apr 2016 12:29:04 GMT
Content-Length: 154
{"errorCode":401,"message":"The event in requested index is outdated and cleared","cause":"the requested history has been cleared [3430/5]","index":4429}
Causes an obscure exception like the one to be thrown:
com.fasterxml.jackson.databind.JsonMappingException: Instantiation of [simple type, class mousio.etcd4j.responses.EtcdKeysResponse] value failed: Name is null
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.wrapException(StdValueInstantiator.java:399) ~[jackson-databind-2.6.5.jar:2.6.5]
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromObjectWith(StdValueInstantiator.java:231) ~[jackson-databind-2.6.5.jar:2.6.5]
at com.fasterxml.jackson.databind.deser.impl.PropertyBasedCreator.build(PropertyBasedCreator.java:135) ~[jackson-databind-2.6.5.jar:2.6.5]
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:442) ~[jackson-databind-2.6.5.jar:2.6.5]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1099) ~[jackson-databind-2.6.5.jar:2.6.5]
at com.fasterxml.jackson.module.afterburner.deser.SuperSonicBeanDeserializer.deserializeFromObject(SuperSonicBeanDeserializer.java:236) ~[jackson-module-afterburner-2.7.0.jar:2.7.0]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:133) ~[jackson-databind-2.6.5.jar:2.6.5]
at com.fasterxml.jackson.module.afterburner.deser.SuperSonicBeanDeserializer.deserialize(SuperSonicBeanDeserializer.java:117) ~[jackson-module-afterburner-2.7.0.jar:2.7.0]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3736) ~[jackson-databind-2.6.5.jar:2.6.5]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2796) ~[jackson-databind-2.6.5.jar:2.6.5]
at mousio.etcd4j.responses.EtcdResponseDecoders$JsonDecoder.decode(EtcdResponseDecoders.java:54) ~[etcd4j-2.10.0.jar:2.10.0]
at mousio.etcd4j.transport.EtcdResponseHandler.channelRead0(EtcdResponseHandler.java:139) [etcd4j-2.10.0.jar:2.10.0]
at mousio.etcd4j.transport.EtcdResponseHandler.channelRead0(EtcdResponseHandler.java:47) [etcd4j-2.10.0.jar:2.10.0]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:439) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:162) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) [netty-codec-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:439) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:162) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:439) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:162) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:433) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:276) [netty-codec-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:263) [netty-codec-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:243) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:439) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:162) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.handler.timeout.ReadTimeoutHandler.channelRead(ReadTimeoutHandler.java:152) [netty-handler-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:439) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:162) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:924) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:125) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:510) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:467) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:381) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:353) [netty-transport-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:742) [netty-common-4.1.0.CR2.jar:4.1.0.CR2]
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137) [netty-common-4.1.0.CR2.jar:4.1.0.CR2]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_71]
Caused by: java.lang.NullPointerException: Name is null
at java.lang.Enum.valueOf(Enum.java:236) ~[na:1.8.0_71]
at mousio.etcd4j.responses.EtcdKeyAction.valueOf(EtcdKeyAction.java:6) ~[etcd4j-2.10.0.jar:2.10.0]
at mousio.etcd4j.responses.EtcdKeysResponse.<init>(EtcdKeysResponse.java:62) ~[etcd4j-2.10.0.jar:2.10.0]
at sun.reflect.GeneratedConstructorAccessor42.newInstance(Unknown Source) ~[na:na]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_71]
at java.lang.reflect.Constructor.newInstance(Constructor.java:422) ~[na:1.8.0_71]
at com.fasterxml.jackson.databind.introspect.AnnotatedConstructor.call(AnnotatedConstructor.java:125) ~[jackson-databind-2.6.5.jar:2.6.5]
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromObjectWith(StdValueInstantiator.java:227) ~[jackson-databind-2.6.5.jar:2.6.5]
... 48 common frames omitted
Hi guys:
When I use the custom method to construct a EtcdClient, I set my NettyEventLoopGroup to EtcdNettyConfig,But when I close EtcdClient, EtcdClient close my NettyEventLoopGroup also.
Maybe if EventLoopGroup is custom set (not the default one), EtcdClient should not close it?
Or have an option to control the behavior?
Thanks!
Would love to see support for watch operations.
This topic https://github.com/coreos/etcd/blob/master/Documentation/errorcode.md defines a set of possible error codes which can etcd server return to your request. The server returns both http status code and json body as well. The server does it even in error states.
On the other hand EtcdKeyResponseHandler parses only some http status codes into EtcdException body.
This means that when I send a request to get not existing key, the etcd client returns EtcdException with error code 101. Contrary to this behavior, when I send a request using prevExist=false and the request fails, a new Exception is thrown containing message "412 Precondition Failed". I need to parse the text using HttpResponseStatus.parseLine in this case to discover what happen.
I would suggest to throw an EtcdException with proper error code in all cases when possible.
When using consistent=true flag such as 'http://127.0.0.1:4001/v2/keys/dir/asdf?consistent=true", etcd4j client gets an exception as following:
com.fasterxml.jackson.core.JsonParseException: Unexpected character ('<' (code 60)): expected a valid value (number, String, array, object, 'true', 'false' or 'null').
Please curl the same url gives the right response.
I want to use etcd4j along with etcd 2.3, released this week it looks like. There is now the option of using the 'refresh=true' parameter so that updating ttl will not trigger a watch. I need a way to use this parameter via etcd4j, and it seems like exposing the parameters to pass along to etcd would be useful. Something like
EtcdKeyRequest.addParam(String param, String value);
Alternatively, updating the api to be compatible with the 2.3 changes would also work. Being able to do
put(key, value).ttl(5).refresh(true).prevExists(true);
Currently it looks like the value param is added on for all put calls, that would have to be changed as well (refresh does not support updating value as well, it just updates ttl).
Are there any plans for adding this? thanks. Z
As today the project is structured as a single project even if it has two main component (source sets):
Then on maven central, there are two jars matching the source sets but:
So I'm thinking if it would be better to convert the project to a multi project or get rid of separate etcd4j-client source set and etcd4j-client jar on maven.
Anything that make sense for you ?
NOTE: Please disregard/delete -- we're using etcd 0.3.0
I'm attempting a simple get as folllows:
EtcdResponsePromise promise = client.get("/my/existing/key").send();
This always results in the message below. It's just a WARNING, so I then try to subsequently read out the promise in a blocking? manner
promise.getNow().node.value
and I will get null, even though the key exists, unless I set breakpoint and wait. This leads me to believe that "getNow()" is asynchronous, but when I do same in a listener, it never fires. Perhaps I'm using this incorrectly?
Sep 25, 2014 3:36:01 PM io.netty.channel.DefaultChannelPipeline$TailContext exceptionCaught
WARNING: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
java.lang.IllegalStateException: complete already: DefaultPromise@3d3c76be(failure(java.util.concurrent.CancellationException)
at io.netty.util.concurrent.DefaultPromise.setFailure(DefaultPromise.java:418)
at mousio.etcd4j.transport.EtcdKeyResponseHandler.channelRead0(EtcdKeyResponseHandler.java:60)
at mousio.etcd4j.transport.EtcdKeyResponseHandler.channelRead0(EtcdKeyResponseHandler.java:15)
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83)
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:153)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:182)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83)
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:153)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:182)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:163)
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83)
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:153)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:182)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:886)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:126)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:510)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:467)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:381)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:353)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:834)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: complete already: DefaultPromise@3d3c76be(failure(java.util.concurrent.CancellationException)
at io.netty.util.concurrent.DefaultPromise.setSuccess(DefaultPromise.java:400)
at mousio.etcd4j.transport.EtcdKeyResponseHandler.channelRead0(EtcdKeyResponseHandler.java:54)
... 22 more
Usually a user should be able to watch over a key / dir for a change and when there is a change the user must be notified. This is useful for dynamic application configuration changes. If i have an app which is configured via ETCD and someone decides to change a single parameter, the application must be able to recognize such event and act upon it.
i.e. change the db host.
Hi there,
I set the put timeout value to be 10 seconds, however, it always throws out an exception in 10 seconds no matter the write succeeded or not.
Below is the log, at 11.926 the write returns successfully, but still at 21.912 an exception happens. Can this exception be avoided? If it is a real exception, can it be thrown to application instead of printing trace underneath? Printing tracing can be very expensive.
Dec 31 2014 12:18:11.926 [main] [Etcd.java:272] DEBUG c.s.c.e.Etcd - Etcd putValue - key GroupId, value 123456, return 123456
Dec 31 2014 12:18:21.912 [nioEventLoopGroup-2-2] [Slf4JLogger.java:151] WARN i.n.c.DefaultChannelPipeline - An exception was thrown by a user handler's exceptionCaught() method:
java.lang.IllegalStateException: complete already: DefaultPromise@282e593e(incomplete)
at io.netty.util.concurrent.DefaultPromise.setFailure(DefaultPromise.java:418) ~[netty-common-4.1.0.Beta3.jar:4.1.0.Beta3]
at mousio.etcd4j.transport.EtcdNettyClient$5.exceptionCaught(EtcdNettyClient.java:233) ~[etcd4j-2.0.0.jar:na]
at io.netty.channel.ChannelHandlerInvokerUtil.invokeExceptionCaughtNow(ChannelHandlerInvokerUtil.java:64) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.DefaultChannelHandlerInvoker.invokeExceptionCaught(DefaultChannelHandlerInvoker.java:110) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.AbstractChannelHandlerContext.fireExceptionCaught(AbstractChannelHandlerContext.java:167) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.ChannelInboundHandlerAdapter.exceptionCaught(ChannelInboundHandlerAdapter.java:131) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.ChannelHandlerInvokerUtil.invokeExceptionCaughtNow(ChannelHandlerInvokerUtil.java:64) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.DefaultChannelHandlerInvoker.invokeExceptionCaught(DefaultChannelHandlerInvoker.java:110) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.AbstractChannelHandlerContext.fireExceptionCaught(AbstractChannelHandlerContext.java:167) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.ChannelInboundHandlerAdapter.exceptionCaught(ChannelInboundHandlerAdapter.java:131) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.ChannelHandlerInvokerUtil.invokeExceptionCaughtNow(ChannelHandlerInvokerUtil.java:64) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.DefaultChannelHandlerInvoker.invokeExceptionCaught(DefaultChannelHandlerInvoker.java:110) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.AbstractChannelHandlerContext.fireExceptionCaught(AbstractChannelHandlerContext.java:167) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.ChannelHandlerAdapter.exceptionCaught(ChannelHandlerAdapter.java:79) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.ChannelHandlerInvokerUtil.invokeExceptionCaughtNow(ChannelHandlerInvokerUtil.java:64) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.DefaultChannelHandlerInvoker.invokeExceptionCaught(DefaultChannelHandlerInvoker.java:110) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.AbstractChannelHandlerContext.fireExceptionCaught(AbstractChannelHandlerContext.java:167) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.ChannelInboundHandlerAdapter.exceptionCaught(ChannelInboundHandlerAdapter.java:131) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.ChannelHandlerInvokerUtil.invokeExceptionCaughtNow(ChannelHandlerInvokerUtil.java:64) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.DefaultChannelHandlerInvoker.invokeExceptionCaught(DefaultChannelHandlerInvoker.java:110) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.AbstractChannelHandlerContext.fireExceptionCaught(AbstractChannelHandlerContext.java:167) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.handler.timeout.ReadTimeoutHandler.readTimedOut(ReadTimeoutHandler.java:186) [netty-handler-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.handler.timeout.ReadTimeoutHandler$ReadTimeoutTask.run(ReadTimeoutHandler.java:212) [netty-handler-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.util.concurrent.PromiseTask$RunnableAdapter.call(PromiseTask.java:38) [netty-common-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.util.concurrent.ScheduledFutureTask.run(ScheduledFutureTask.java:123) [netty-common-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:343) [netty-common-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:356) [netty-transport-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:834) [netty-common-4.1.0.Beta3.jar:4.1.0.Beta3]
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137) [netty-common-4.1.0.Beta3.jar:4.1.0.Beta3]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_20]
Caused by: io.netty.handler.timeout.ReadTimeoutException: null
Dec 31 2014 12:18:21.913 [nioEventLoopGroup-2-2] [Slf4JLogger.java:151] WARN i.n.c.DefaultChannelPipeline - .. and the cause of the exceptionCaught() was:
io.netty.handler.timeout.ReadTimeoutException: null
Thanks,
Ken
When using the latest source code version (528ed00) the classes in the new mousio.client package are missing in the jar. I fixed it locally with this commit:
https://github.com/slintes/etcd4j/commit/eefca9f68a93982ffb0ee3497aa580433a80aae6
No pull request yet because I don't know what your plan with the package is, and it might be work in progress :)
consistent=true can not be set through the API. It should be added to the EtcdKeyGetRequest
watch key wait for changing.When server return error code 401,etcd4j can not handler,
EtcdResponseHandler class should add
failureDecoders.put(HttpResponseStatus.BAD_REQUEST, EtcdException.DECODER);
since a IsSimplePromiseResponseHandler is added after a request was send, it can happen (and for us did happen very often) that the response (or exception) was already received before the handler is added. The handler is not called in this case and waits forever. PR follows.
such as when create client with
EtcdClient etcd = new EtcdClient(
URI.create("http://123.45.67.89:8001"),
URI.create("http://123.45.67.90:8001"));
if the list's first etcd server 123.45.67.89:8001 down, always retry but not get connect to second etcd server.
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.