private void handleStateChange(ConnectionState newState) {
    switch (newState) {
      default:
        {
          // NOP
          break;
        }

      case RECONNECTED:
        {
          try {
            reset();
          } catch (Exception e) {
            log.error("Could not reset leader latch", e);
            setLeadership(false);
          }
          break;
        }

      case SUSPENDED:
      case LOST:
        {
          setLeadership(false);
          break;
        }
    }
  }
  @VisibleForTesting
  void reset() throws Exception {
    setLeadership(false);
    setNode(null);

    BackgroundCallback callback =
        new BackgroundCallback() {
          @Override
          public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
            if (debugResetWaitLatch != null) {
              debugResetWaitLatch.await();
              debugResetWaitLatch = null;
            }

            if (event.getResultCode() == KeeperException.Code.OK.intValue()) {
              setNode(event.getName());
              getChildren();
            } else {
              log.error("getChildren() failed. rc = " + event.getResultCode());
            }
          }
        };
    client
        .create()
        .creatingParentsIfNeeded()
        .withProtection()
        .withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
        .inBackground(callback)
        .forPath(ZKPaths.makePath(latchPath, LOCK_NAME), LeaderSelector.getIdBytes(id));
  }
Example #3
0
  /**
   * Remove this instance from the leadership election. If this instance is the leader, leadership
   * is released. IMPORTANT: the only way to release leadership is by calling close(). All
   * LeaderLatch instances must eventually be closed.
   *
   * @throws IOException errors
   */
  @Override
  public void close() throws IOException {
    Preconditions.checkState(state.compareAndSet(State.STARTED, State.CLOSED), "Not started");

    try {
      client.delete().guaranteed().inBackground().forPath(ourPath);
    } catch (Exception e) {
      throw new IOException(e);
    } finally {
      client.getConnectionStateListenable().removeListener(listener);
      setLeadership(false);
    }
  }
  /**
   * Remove this instance from the leadership election. If this instance is the leader, leadership
   * is released. IMPORTANT: the only way to release leadership is by calling close(). All
   * LeaderLatch instances must eventually be closed.
   *
   * @throws IOException errors
   */
  @Override
  public void close() throws IOException {
    Preconditions.checkState(
        state.compareAndSet(State.STARTED, State.CLOSED), "Already closed or has not been started");

    try {
      setNode(null);
    } catch (Exception e) {
      throw new IOException(e);
    } finally {
      client.getConnectionStateListenable().removeListener(listener);
      setLeadership(false);
    }
  }
Example #5
0
  private void handleStateChange(ConnectionState newState) {
    if (newState == ConnectionState.RECONNECTED) {
      newState = ConnectionState.CONNECTED;
    }

    ConnectionState previousState = connectionState.getAndSet(newState);
    if ((previousState == ConnectionState.LOST) && (newState == ConnectionState.CONNECTED)) {
      try {
        internalStart();
      } catch (Exception e) {
        log.error("Could not restart leader latch", e);
        connectionState.set(ConnectionState.LOST);
        setLeadership(false);
      }
    }
  }
  private void checkLeadership(List<String> children) throws Exception {
    final String localOurPath = ourPath.get();
    List<String> sortedChildren = LockInternals.getSortedChildren(LOCK_NAME, sorter, children);
    int ourIndex =
        (localOurPath != null) ? sortedChildren.indexOf(ZKPaths.getNodeFromPath(localOurPath)) : -1;
    if (ourIndex < 0) {
      log.error("Can't find our node. Resetting. Index: " + ourIndex);
      reset();
    } else if (ourIndex == 0) {
      setLeadership(true);
    } else {
      String watchPath = sortedChildren.get(ourIndex - 1);
      Watcher watcher =
          new Watcher() {
            @Override
            public void process(WatchedEvent event) {
              if ((state.get() == State.STARTED)
                  && (event.getType() == Event.EventType.NodeDeleted)
                  && (localOurPath != null)) {
                try {
                  getChildren();
                } catch (Exception ex) {
                  log.error("An error occurred checking the leadership.", ex);
                }
              }
            }
          };

      BackgroundCallback callback =
          new BackgroundCallback() {
            @Override
            public void processResult(CuratorFramework client, CuratorEvent event)
                throws Exception {
              if (event.getResultCode() == KeeperException.Code.NONODE.intValue()) {
                // previous node is gone - reset
                reset();
              }
            }
          };
      client
          .checkExists()
          .usingWatcher(watcher)
          .inBackground(callback)
          .forPath(ZKPaths.makePath(latchPath, watchPath));
    }
  }
Example #7
0
  private void checkForLeadership() throws Exception {
    List<String> sortedChildren =
        LockInternals.getSortedChildren(client, latchPath, LOCK_NAME, sorter);
    if (sortedChildren.size() == 0) {
      throw new Exception("no children - unexpected state");
    }

    int ourIndex = sortedChildren.indexOf(ZKPaths.getNodeFromPath(ourPath));
    if (ourIndex == 0) {
      setLeadership(true);
    } else {
      final String ourPathWhenWatched =
          ourPath; // protected against a lost/suspended connection and an old watcher - I'm not
                   // sure if this is possible but it can't hurt
      String watchPath = sortedChildren.get(ourIndex - 1);
      Watcher watcher =
          new Watcher() {
            @Override
            public void process(WatchedEvent event) {
              if ((event.getType() == Event.EventType.NodeDeleted)
                  && (ourPath != null)
                  && ourPath.equals(ourPathWhenWatched)) {
                try {
                  checkForLeadership();
                } catch (Exception ex) {
                  log.error("An error ocurred checking the leadership.", ex);
                }
              }
            }
          };
      if (client.checkExists().usingWatcher(watcher).forPath(ZKPaths.makePath(latchPath, watchPath))
          == null) {
        // the previous Participant may be down, so we need to reevaluate the list
        // to get the actual previous Participant or get the leadership
        checkForLeadership();
      }
    }
  }