jurmous / etcd4j

Java / Netty client for etcd, the highly-available key value store for shared configuration and service discovery.
Apache License 2.0
267 stars 83 forks source link

Trying to connect to an invalid socket/port comibnation and using 'watch' functionality stack overflow #122

Closed sheinbergon closed 7 years ago

sheinbergon commented 8 years ago

Hi

Due to a configuration issue back at our we tried to connect to an invalid etcd port and watch a directory. In such a scenario , the class EtcdResponsePromise get method creates what will eventually become a stack overflow :

  @Override public T get() throws IOException, EtcdException, EtcdAuthenticationException, TimeoutException {
    if (!waitForPromiseSuccess()) {
      return this.get();
    }

    if (response != null) {
      return response;
    } else {
      if (this.exception instanceof EtcdException) {
        throw (EtcdException) this.exception;
      } if (this.exception instanceof EtcdAuthenticationException) {
        throw (EtcdAuthenticationException) this.exception;
      } else if (this.exception instanceof IOException) {
        throw (IOException) this.exception;
      } else if (this.exception instanceof io.netty.handler.timeout.TimeoutException) {
        throw new TimeoutException();
      } else {
        throw new IOException(this.exception);
      }
    }
  }

Basically waitForPromiseSuccess returns false and get is called again . The external watchRequest is never notified of error due to the way your underlying code , and were are left with ever increasing stack for the threads in question

Actual output from a threaddump running on my machine

    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:59)
lburgazzoli commented 7 years ago

Is still happening ? If yes, any chance to have a test case so I can look @ it ?

sheinbergon commented 7 years ago

@lburgazzoli don't know , will try and check against snapshot next week and I'll let you know

lburgazzoli commented 7 years ago

etcd4j 2.13.0 has been released, do you mind testing against this ?

sheinbergon commented 7 years ago

@lburgazzoli Sure. I'll test in the next couple of days and let you know