public CompletableFuture<ClientSecureChannel> getChannel() {
    State currentState = state.get();

    logger.trace("getChannel(), currentState={}", currentState.getClass().getSimpleName());

    if (currentState instanceof Idle) {
      Connecting nextState = new Connecting();

      if (state.compareAndSet(currentState, nextState)) {
        CompletableFuture<ClientSecureChannel> connected = nextState.connected;

        connect(true, connected);

        return connected.whenCompleteAsync(
            (sc, ex) -> {
              if (sc != null) {
                if (state.compareAndSet(nextState, new Connected(connected))) {
                  sc.getChannel().pipeline().addLast(new InactivityHandler());
                }
              } else {
                state.compareAndSet(nextState, new Idle());
              }
            });
      } else {
        return getChannel();
      }
    } else if (currentState instanceof Connecting) {
      return ((Connecting) currentState).connected;
    } else if (currentState instanceof Connected) {
      return ((Connected) currentState).connected;
    } else if (currentState instanceof Reconnecting) {
      return ((Reconnecting) currentState).reconnected;
    } else if (currentState instanceof Disconnecting) {
      CompletableFuture<ClientSecureChannel> future = new CompletableFuture<>();

      CompletableFuture<Unit> disconnectFuture = ((Disconnecting) currentState).disconnectFuture;

      disconnectFuture.whenCompleteAsync(
          (u, ex) ->
              getChannel()
                  .whenCompleteAsync(
                      (sc, ex2) -> {
                        if (sc != null) future.complete(sc);
                        else future.completeExceptionally(ex2);
                      }),
          client.getExecutorService());

      return future;
    } else {
      throw new IllegalStateException(currentState.getClass().getSimpleName());
    }
  }
    @Override
    public void run() {
      while (running.get()) {
        switch (random.nextInt() % 2) {
          case 0: // start a server
            try {
              cluster.startServer();
            } catch (Exception e) {
              LOG.warn(e);
              exception.compareAndSet(null, e);
            }
            break;

          case 1: // stop a server
            try {
              cluster.stopRandomServer();
            } catch (Exception e) {
              LOG.warn(e);
              exception.compareAndSet(null, e);
            }
          default:
        }

        Threads.sleep(100);
      }
    }
  /**
   * Called to indicate that the last write has been performed. It updates the state and performs
   * cleanup operations.
   */
  void closed() {
    while (true) {
      OutputState state = _state.get();
      switch (state) {
        case CLOSED:
          {
            return;
          }
        case UNREADY:
          {
            if (_state.compareAndSet(state, OutputState.ERROR))
              _writeListener.onError(
                  _onError == null ? new EofException("Async closed") : _onError);
            break;
          }
        default:
          {
            if (!_state.compareAndSet(state, OutputState.CLOSED)) break;

            try {
              _channel.getResponse().closeOutput();
            } catch (Throwable x) {
              if (LOG.isDebugEnabled()) LOG.debug(x);
              abort(x);
            } finally {
              releaseBuffer();
            }
            // Return even if an exception is thrown by closeOutput().
            return;
          }
      }
    }
  }
  /** @see javax.servlet.ServletOutputStream#isReady() */
  @Override
  public boolean isReady() {
    while (true) {
      switch (_state.get()) {
        case OPEN:
          return true;

        case ASYNC:
          if (!_state.compareAndSet(OutputState.ASYNC, OutputState.READY)) continue;
          return true;

        case READY:
          return true;

        case PENDING:
          if (!_state.compareAndSet(OutputState.PENDING, OutputState.UNREADY)) continue;
          return false;

        case UNREADY:
          return false;

        case ERROR:
          return true;

        case CLOSED:
          return true;

        default:
          throw new IllegalStateException();
      }
    }
  }
Exemple #5
0
  public boolean analyze(
      @NotNull PsiFile file,
      TextRange dirtyScope,
      @NotNull Runnable analyze,
      @NotNull ProgressIndicator indicator) {
    ProgressIndicator old = myState.get();
    if (old != VIRGIN && old != READY) return false;
    if (!myState.compareAndSet(old, indicator)) {
      log("a: failed to change ", old, "->", indicator);
      return false;
    }
    log("a: changed ", old, "->", indicator);
    analyzedUnder = null;
    boolean completed = false;
    try {
      if (dirtyScope != null) {
        if (dirtyScope.equals(file.getTextRange())) {
          clear();
        } else {
          removeInvalidRefs();
        }
      }

      analyze.run();
      analyzedUnder = indicator;
      completed = true;
    } finally {
      ProgressIndicator resultState = completed ? READY : VIRGIN;
      boolean set = myState.compareAndSet(indicator, resultState);
      assert set : myState.get();
      log("a: changed after analyze", indicator, "->", resultState);
    }
    return true;
  }
  private void reconnect(Reconnecting reconnectState, long delaySeconds) {
    logger.debug("Scheduling reconnect for +{} seconds...", delaySeconds);

    Stack.sharedScheduledExecutor()
        .schedule(
            () -> {
              logger.debug("{} seconds elapsed; reconnecting...", delaySeconds);

              CompletableFuture<ClientSecureChannel> reconnected = reconnectState.reconnected;

              connect(true, reconnected);

              reconnected.whenCompleteAsync(
                  (sc, ex) -> {
                    if (sc != null) {
                      logger.debug("Reconnect succeeded, channelId={}", sc.getChannelId());

                      if (state.compareAndSet(reconnectState, new Connected(reconnected))) {
                        sc.getChannel().pipeline().addLast(new InactivityHandler());
                      }
                    } else {
                      logger.debug("Reconnect failed: {}", ex.getMessage(), ex);

                      Reconnecting nextState = new Reconnecting();
                      if (state.compareAndSet(reconnectState, nextState)) {
                        reconnect(nextState, nextDelay(delaySeconds));
                      }
                    }
                  });
            },
            delaySeconds,
            TimeUnit.SECONDS);
  }
 @Override
 public CloseFuture close(boolean immediately) {
   if (immediately) {
     if (state.compareAndSet(State.Opened, State.Immediate)
         || state.compareAndSet(State.Graceful, State.Immediate)) {
       if (log.isDebugEnabled()) {
         log.debug("close({}) Closing immediately", this);
       }
       preClose();
       doCloseImmediately();
       if (log.isDebugEnabled()) {
         log.debug("close({})[Immediately] closed", this);
       }
     } else {
       if (log.isDebugEnabled()) {
         log.debug("close({})[Immediately] state already {}", this, state.get());
       }
     }
   } else {
     if (state.compareAndSet(State.Opened, State.Graceful)) {
       if (log.isDebugEnabled()) {
         log.debug("close({}) Closing gracefully", this);
       }
       preClose();
       SshFuture<CloseFuture> grace = doCloseGracefully();
       if (grace != null) {
         grace.addListener(
             new SshFutureListener<CloseFuture>() {
               @Override
               @SuppressWarnings("synthetic-access")
               public void operationComplete(CloseFuture future) {
                 if (state.compareAndSet(State.Graceful, State.Immediate)) {
                   doCloseImmediately();
                   if (log.isDebugEnabled()) {
                     log.debug(
                         "close({}][Graceful] - operationComplete() closed",
                         AbstractCloseable.this);
                   }
                 }
               }
             });
       } else {
         if (state.compareAndSet(State.Graceful, State.Immediate)) {
           doCloseImmediately();
           if (log.isDebugEnabled()) {
             log.debug("close({})[Graceful] closed", this);
           }
         }
       }
     } else {
       if (log.isDebugEnabled()) {
         log.debug("close({})[Graceful] state already {}", this, state.get());
       }
     }
   }
   return closeFuture;
 }
 /**
  * Ensures that |sDefaultTrustManager| and |sCertificateFactory| are initialized.
  *
  * @throws CertificateException,KeyStoreException,NoSuchAlgorithmException on error initializing
  *     the TrustManager.
  */
 private static void ensureInitialized()
     throws CertificateException, KeyStoreException, NoSuchAlgorithmException {
   // There could be a begin race creating two instances of these objects, which
   // is harmless save for a bit of wasted effort.
   if (sDefaultTrustManager.get() == null) {
     sDefaultTrustManager.compareAndSet(null, createDefaultTrustManager());
   }
   if (sCertificateFactory.get() == null) {
     sCertificateFactory.compareAndSet(null, CertificateFactory.getInstance("X.509"));
   }
 }
 public void process(Runnable aTask) {
   Scripts.LocalContext context = Scripts.getContext();
   Runnable taskWrapper =
       () -> {
         Scripts.setContext(context);
         try {
           aTask.run();
         } finally {
           Scripts.setContext(null);
         }
       };
   queue.offer(taskWrapper);
   offerTask(
       () -> {
         // Runnable processedTask = taskWrapper;
         int version;
         int newVersion;
         Thread thisThread = Thread.currentThread();
         do {
           version = queueVersion.get();
           // Zombie counter ...
           newVersion = version + 1;
           if (newVersion == Integer.MAX_VALUE) {
             newVersion = 0;
           }
           /* moved to top of body
           if (processedTask != null) {//Single attempt to offer aTask.
           queue.offer(processedTask);
           processedTask = null;
           }
           */
           if (worker.compareAndSet(null, thisThread)) { // Worker electing.
             try {
               // already single threaded environment
               if (global == null) {
                 Scripts.Space.this.initSpaceGlobal();
               }
               // Zombie processing ...
               Runnable task = queue.poll();
               while (task != null) {
                 task.run();
                 task = queue.poll();
               }
             } catch (Throwable t) {
               Logger.getLogger(Scripts.class.getName()).log(Level.SEVERE, null, t);
             } finally {
               boolean setted = worker.compareAndSet(thisThread, null);
               assert setted : "Worker electing assumption failed"; // Always successfull CAS.
             }
           }
         } while (!queueVersion.compareAndSet(version, newVersion));
       });
 }
Exemple #10
0
  @Override
  public void write(int b) throws IOException {
    _written += 1;
    boolean complete = _channel.getResponse().isAllContentWritten(_written);

    // Async or Blocking ?
    while (true) {
      switch (_state.get()) {
        case OPEN:
          if (_aggregate == null)
            _aggregate = _channel.getByteBufferPool().acquire(getBufferSize(), false);
          BufferUtil.append(_aggregate, (byte) b);

          // Check if all written or full
          if (complete || BufferUtil.isFull(_aggregate)) {
            BlockingCallback callback = _channel.getWriteBlockingCallback();
            _channel.write(_aggregate, complete, callback);
            callback.block();
            if (complete) closed();
          }
          break;

        case ASYNC:
          throw new IllegalStateException("isReady() not called");

        case READY:
          if (!_state.compareAndSet(State.READY, State.PENDING)) continue;

          if (_aggregate == null)
            _aggregate = _channel.getByteBufferPool().acquire(getBufferSize(), false);
          BufferUtil.append(_aggregate, (byte) b);

          // Check if all written or full
          if (!complete && !BufferUtil.isFull(_aggregate)) {
            if (!_state.compareAndSet(State.PENDING, State.ASYNC))
              throw new IllegalStateException();
            return;
          }

          // Do the asynchronous writing from the callback
          new AsyncFlush().process();
          return;

        case PENDING:
        case UNREADY:
          throw new WritePendingException();

        case CLOSED:
          throw new EofException("Closed");
      }
      break;
    }
  }
 private static void doClear(
     ThrowableRunnable<StorageException> clearAction, AtomicReference<RebuildStatus> status)
     throws StorageException {
   try {
     clearAction.run();
   } catch (StorageException e) {
     status.compareAndSet(DOING_REBUILD, REQUIRES_REBUILD);
     throw e;
   }
   if (!status.compareAndSet(DOING_REBUILD, OK)) {
     FileBasedIndexImpl.LOG.error("Unexpected status " + status.get());
   }
 }
    /* ------------------------------------------------------------ */
    protected void invalidate() {
      ByteBuffer indirect = _indirectBuffer.get();
      if (indirect != null && _indirectBuffer.compareAndSet(indirect, null))
        _cachedSize.addAndGet(-BufferUtil.length(indirect));

      ByteBuffer direct = _directBuffer.get();
      if (direct != null
          && !BufferUtil.isMappedBuffer(direct)
          && _directBuffer.compareAndSet(direct, null))
        _cachedSize.addAndGet(-BufferUtil.length(direct));

      _cachedFiles.decrementAndGet();
      _resource.close();
    }
 public void registerGlobal(final Serializer serializer) {
   SerializerAdapter adapter = createSerializerAdapter(serializer);
   if (!global.compareAndSet(null, adapter)) {
     throw new IllegalStateException("Global serializer is already registered!");
   }
   SerializerAdapter current = idMap.putIfAbsent(serializer.getTypeId(), adapter);
   if (current != null && current.getImpl().getClass() != adapter.getImpl().getClass()) {
     global.compareAndSet(adapter, null);
     throw new IllegalStateException(
         "Serializer ["
             + current.getImpl()
             + "] has been already registered for type-id: "
             + serializer.getTypeId());
   }
 }
Exemple #14
0
  @Override
  public void flush() throws IOException {
    while (true) {
      switch (_state.get()) {
        case OPEN:
          write(BufferUtil.hasContent(_aggregate) ? _aggregate : BufferUtil.EMPTY_BUFFER, false);
          return;

        case ASYNC:
          throw new IllegalStateException("isReady() not called");

        case READY:
          if (!_state.compareAndSet(OutputState.READY, OutputState.PENDING)) continue;
          new AsyncFlush().iterate();
          return;

        case PENDING:
          return;

        case UNREADY:
          throw new WritePendingException();

        case ERROR:
          throw new EofException(_onError);

        case CLOSED:
          return;

        default:
          throw new IllegalStateException();
      }
    }
  }
Exemple #15
0
  /**
   * Asynchronous send of HTTP content.
   *
   * @param httpContent The HTTP content to send
   * @param callback The callback to use to notify success or failure
   */
  public void sendContent(HttpContent httpContent, Callback callback) {
    if (LOG.isDebugEnabled()) LOG.debug("sendContent(http={},{})", httpContent, callback);

    if (BufferUtil.hasContent(_aggregate)) {
      callback.failed(new IOException("cannot sendContent() after write()"));
      return;
    }
    if (_channel.isCommitted()) {
      callback.failed(new IOException("committed"));
      return;
    }

    while (true) {
      switch (_state.get()) {
        case OPEN:
          if (!_state.compareAndSet(OutputState.OPEN, OutputState.PENDING)) continue;
          break;

        case ERROR:
          callback.failed(new EofException(_onError));
          return;

        case CLOSED:
          callback.failed(new EofException("Closed"));
          return;

        default:
          throw new IllegalStateException();
      }
      break;
    }

    ByteBuffer buffer = _channel.useDirectBuffers() ? httpContent.getDirectBuffer() : null;
    if (buffer == null) buffer = httpContent.getIndirectBuffer();

    if (buffer != null) {
      sendContent(buffer, callback);
      return;
    }

    try {
      ReadableByteChannel rbc = httpContent.getReadableByteChannel();
      if (rbc != null) {
        // Close of the rbc is done by the async sendContent
        sendContent(rbc, callback);
        return;
      }

      InputStream in = httpContent.getInputStream();
      if (in != null) {
        sendContent(in, callback);
        return;
      }

      throw new IllegalArgumentException("unknown content for " + httpContent);
    } catch (Throwable th) {
      abort(th);
      callback.failed(th);
    }
  }
  /**
   * Start the server running - accepting connections, receiving messages. If the server is already
   * running, it will not be started again. This method is designed to be called in its own thread
   * and will not return until the server is stopped.
   *
   * @throws RuntimeException if the server fails
   */
  public void run() {
    // ensure that the server is not started twice
    if (!state.compareAndSet(State.STOPPED, State.RUNNING)) {
      started(true);
      return;
    }

    Selector selector = null;
    ServerSocketChannel server = null;
    try {
      selector = Selector.open();
      server = ServerSocketChannel.open();
      server.socket().bind(new InetSocketAddress(port));
      server.configureBlocking(false);
      server.register(selector, SelectionKey.OP_ACCEPT);
      started(false);
      while (state.get() == State.RUNNING) {
        selector.select(100); // check every 100ms whether the server has been requested to stop
        for (Iterator<SelectionKey> it = selector.selectedKeys().iterator(); it.hasNext(); ) {
          SelectionKey key = it.next();
          try {
            // remove key from the ready list
            it.remove();
            if (key.isConnectable()) {
              ((SocketChannel) key.channel()).finishConnect();
            }
            if (key.isAcceptable()) {
              // accept connection
              SocketChannel client = server.accept();
              client.configureBlocking(false);
              client.socket().setTcpNoDelay(true);
              // channel is registered for further events such as read or write
              SelectionKey acceptKey = client.register(selector, SelectionKey.OP_READ);
              connection(acceptKey);
            }
            if (key.isReadable()) {
              for (ByteBuffer message : readIncomingMessage(key)) {
                messageReceived(message, key);
              }
            }
          } catch (IOException ioe) {
            resetKey(key);
            disconnected(key);
          }
        }
      }
    } catch (Throwable e) {
      throw new RuntimeException("Server failure: " + e.getMessage());
    } finally {
      try {
        selector.close();
        server.socket().close();
        server.close();
        state.set(State.STOPPED);
        stopped();
      } catch (Exception e) {
        // do nothing - server failed
      }
    }
  }
  /**
   * Add this instance to the leadership election and attempt to acquire leadership.
   *
   * @throws Exception errors
   */
  public void start() throws Exception {
    Preconditions.checkState(
        state.compareAndSet(State.LATENT, State.STARTED), "Cannot be started more than once");

    client.getConnectionStateListenable().addListener(listener);
    reset();
  }
 public void unsubscribe() {
   Subscription s = rollingDistributionSubscription.get();
   if (s != null) {
     s.unsubscribe();
     rollingDistributionSubscription.compareAndSet(s, null);
   }
 }
Exemple #19
0
 /**
  * Remove all configuration values under a single section.
  *
  * @param section section name, e.g "branch"
  * @param subsection optional subsection value, e.g. a branch name
  */
 public void unsetSection(String section, String subsection) {
   State src, res;
   do {
     src = state.get();
     res = unsetSection(src, section, subsection);
   } while (!state.compareAndSet(src, res));
 }
    @Override
    public void run() {
      while (running.get()) {
        boolean isBigPayload = random.nextBoolean();
        String message = isBigPayload ? BIG_PAYLOAD : id + numCalls;
        EchoRequestProto param = EchoRequestProto.newBuilder().setMessage(message).build();
        EchoResponseProto ret;
        TestRpcServer server = cluster.getRandomServer();
        try {
          sending.set(true);
          BlockingInterface stub = newBlockingStub(rpcClient, server.getListenerAddress());
          ret = stub.echo(null, param);
        } catch (Exception e) {
          LOG.warn(e);
          continue; // expected in case connection is closing or closed
        }

        try {
          assertNotNull(ret);
          assertEquals(message, ret.getMessage());
        } catch (Throwable t) {
          exception.compareAndSet(null, t);
        }

        numCalls++;
      }
    }
 @Nullable
 public static StubIndexImpl getInstanceOrInvalidate() {
   if (ourForcedClean.compareAndSet(null, Boolean.TRUE)) {
     return null;
   }
   return (StubIndexImpl) getInstance();
 }
  private void dispatchTasks(CancellationToken cancelToken) {
    if (isCurrentThreadDispatching()) {
      // Tasks will be dispatched there.
      return;
    }

    Thread currentThread = Thread.currentThread();
    Throwable toThrow = null;
    while (!isQueueEmpty()) {
      if (dispatcherThread.compareAndSet(null, currentThread)) {
        try {
          TaskDef taskDef = pollFromQueue();
          if (taskDef != null) {
            taskDef.doTask(cancelToken);
          }
        } catch (Throwable ex) {
          // Only in a case of a very serious error (like OutOfMemory)
          // will this block be executed because exceptions thrown
          // by the task (and the cleanup task) is caught and logged.
          if (toThrow == null) toThrow = ex;
          else toThrow.addSuppressed(ex);
        } finally {
          dispatcherThread.set(null);
        }
      } else {
        return;
      }
    }

    ExceptionHelper.rethrowIfNotNull(toThrow);
  }
 /**
  * If no thread has been spawned so far, spawns a new one that will perform the cache init.
  * Optionally waits for the cache initialization to be performed in a another thread.
  */
 private void useNewThreadToInitialize(boolean wait) {
   if (wait && isWorkspaceLockedByCurrentThread()) {
     // may not wait if we currently hold a conflicting rule
     throw new IllegalStateException(
         "Cannot wait for the thread to finish if we currently hold the WS lock");
   }
   CountDownLatch myGuard = initializerGuard.get();
   // check if there was already a thread scheduled
   if (myGuard == null) {
     // no guard found so far
     final CountDownLatch newGuard = new CountDownLatch(1);
     if (initializerGuard.compareAndSet(null, newGuard)) {
       // still no other thread created a guard in the (short) meantime
       myGuard = newGuard;
       // aquire the WS rule in an own thread and perform the initialization from there
       startInitializerThread(newGuard);
     } else {
       // use the guard that was created by another thread
       myGuard = initializerGuard.get();
     }
   }
   if (myGuard == null) {
     throw new IllegalStateException();
   }
   if (wait) {
     try {
       // optionally wait for the initialization to finish
       myGuard.await();
     } catch (InterruptedException e) {
       // ignore
     }
   }
 }
 @Override
 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
   exception.compareAndSet(null, cause);
   // System.err.print("[" + Thread.currentThread().getName() + "] ");
   // cause.printStackTrace();
   super.exceptionCaught(ctx, cause);
 }
 /**
  * Retrieve instance of {@link HystrixEventNotifier} to use based on order of precedence as
  * defined in {@link HystrixPlugins} class header.
  *
  * <p>Override default by using {@link #registerEventNotifier(HystrixEventNotifier)} or setting
  * property: <code>hystrix.plugin.HystrixEventNotifier.implementation</code> with the full
  * classname to load.
  *
  * @return {@link HystrixEventNotifier} implementation to use
  */
 public HystrixEventNotifier getEventNotifier() {
   if (notifier.get() == null) {
     // check for an implementation from System.getProperty first
     Object impl = getPluginImplementationViaProperty(HystrixEventNotifier.class);
     if (impl == null) {
       // nothing set via properties so initialize with default
       notifier.compareAndSet(null, HystrixEventNotifierDefault.getInstance());
       // we don't return from here but call get() again in case of thread-race so the winner will
       // always get returned
     } else {
       // we received an implementation from the system property so use it
       notifier.compareAndSet(null, (HystrixEventNotifier) impl);
     }
   }
   return notifier.get();
 }
 /**
  * Retrieve instance of {@link HystrixPropertiesStrategy} to use based on order of precedence as
  * defined in {@link HystrixPlugins} class header.
  *
  * <p>Override default by using {@link #registerPropertiesStrategy(HystrixPropertiesStrategy)} or
  * setting property (via Archaius): <code>hystrix.plugin.HystrixPropertiesStrategy.implementation
  * </code> with the full classname to load.
  *
  * @return {@link HystrixPropertiesStrategy} implementation to use
  */
 public HystrixPropertiesStrategy getPropertiesStrategy() {
   if (propertiesFactory.get() == null) {
     // check for an implementation from Archaius first
     Object impl = getPluginImplementationViaArchaius(HystrixPropertiesStrategy.class);
     if (impl == null) {
       // nothing set via Archaius so initialize with default
       propertiesFactory.compareAndSet(null, HystrixPropertiesStrategyDefault.getInstance());
       // we don't return from here but call get() again in case of thread-race so the winner will
       // always get returned
     } else {
       // we received an implementation from Archaius so use it
       propertiesFactory.compareAndSet(null, (HystrixPropertiesStrategy) impl);
     }
   }
   return propertiesFactory.get();
 }
 public void update(EncodingStats newStats) {
   while (true) {
     EncodingStats current = stats.get();
     EncodingStats updated = current.mergeWith(newStats);
     if (stats.compareAndSet(current, updated)) return;
   }
 }
Exemple #28
0
  /**
   * The local endpoint has reached a write failure.
   *
   * <p>A low level I/O failure, or even a jetty side EndPoint close (from idle timeout) are a few
   * scenarios
   *
   * @param t the throwable that caused the write failure
   */
  public void onWriteFailure(Throwable t) {
    ConnectionState event = null;
    synchronized (this) {
      if (this.state == ConnectionState.CLOSED) {
        // already closed
        return;
      }

      // Build out Close Reason
      String reason = "WebSocket Write Failure";
      if (t instanceof EOFException) {
        reason = "WebSocket Write EOF";
        Throwable cause = t.getCause();
        if ((cause != null) && (StringUtil.isNotBlank(cause.getMessage()))) {
          reason = "EOF: " + cause.getMessage();
        }
      } else {
        if (StringUtil.isNotBlank(t.getMessage())) {
          reason = t.getMessage();
        }
      }

      CloseInfo close = new CloseInfo(StatusCode.ABNORMAL, reason);

      finalClose.compareAndSet(null, close);

      this.cleanClose = false;
      this.state = ConnectionState.CLOSED;
      this.inputAvailable = false;
      this.outputAvailable = false;
      this.closeHandshakeSource = CloseHandshakeSource.ABNORMAL;
      event = this.state;
    }
    notifyStateListeners(event);
  }
  @Override
  public void start() {
    log.info("Starting");
    if (!state.compareAndSet(CuratorFrameworkState.LATENT, CuratorFrameworkState.STARTED)) {
      IllegalStateException error = new IllegalStateException();
      log.error("Cannot be started more than once", error);
      throw error;
    }

    try {
      connectionStateManager.start(); // ordering dependency - must be called before client.start()
      client.start();
      executorService =
          Executors.newFixedThreadPool(2, threadFactory); // 1 for listeners, 1 for background ops

      executorService.submit(
          new Callable<Object>() {
            @Override
            public Object call() throws Exception {
              backgroundOperationsLoop();
              return null;
            }
          });
    } catch (Exception e) {
      handleBackgroundOperationException(null, e);
    }
  }
 /**
  * Retrieve instance of {@link HystrixCommandExecutionHook} to use based on order of precedence as
  * defined in {@link HystrixPlugins} class header.
  *
  * <p>Override default by using {@link #registerCommandExecutionHook(HystrixCommandExecutionHook)}
  * or setting property (via Archaius): <code>
  * hystrix.plugin.HystrixCommandExecutionHook.implementation</code> with the full classname to
  * load.
  *
  * @return {@link HystrixCommandExecutionHook} implementation to use
  * @since 1.2
  */
 public HystrixCommandExecutionHook getCommandExecutionHook() {
   if (commandExecutionHook.get() == null) {
     // check for an implementation from Archaius first
     Object impl = getPluginImplementationViaArchaius(HystrixCommandExecutionHook.class);
     if (impl == null) {
       // nothing set via Archaius so initialize with default
       commandExecutionHook.compareAndSet(null, HystrixCommandExecutionHookDefault.getInstance());
       // we don't return from here but call get() again in case of thread-race so the winner will
       // always get returned
     } else {
       // we received an implementation from Archaius so use it
       commandExecutionHook.compareAndSet(null, (HystrixCommandExecutionHook) impl);
     }
   }
   return commandExecutionHook.get();
 }