public boolean updateLeadershipFor()

in iep-spring-leader-redis-cluster/src/main/java/com/netflix/iep/leader/redis/RedisClusterLeaderDatabase.java [92:150]


  public boolean updateLeadershipFor(ResourceId resourceId) {
    // note slight race here where the follower could overtake the leader if it fails. In that
    // case, the watch and transaction should fail and we'd return a false.
    String key = getKey(resourceId);
    int slot = JedisClusterCRC16.getSlot(key);
    try {
      try (Jedis client = jedis.leaderForSlot(slot)) {
        String watchResult = client.watch(key);
        if (watchResult == null || !watchResult.equals("OK")) {
          logger.warn("Invalid watch response: {}", watchResult);
          return false;
        }

        try {
          String data = client.get(key);
          if (data != null && data.equals(leaderString)) {
            Transaction transaction = client.multi();
            transaction.set(key, leaderString, updateParams);
            List<Object> results = transaction.exec();
            if (results != null &&
                results.size() > 0 &&
                results.get(0) != null &&
                results.get(0).equals("OK")) {
              data = client.get(key);
              if (data == null || !data.equals(leaderString)) {
                logger.warn("Successfully executed renewal transaction but leader " +
                    "was still {}", data);
                return false;
              } else {
                logger.debug("Updated leader key {}", key);
                return true;
              }
            } else {
              // fall-through
              logger.debug("Unable to update our leader status. Trying to capture again.");
            }
          }

          return tryToAcquire(client, key);

        } catch (Exception ex) {
          logger.error("Unexpected exception updating leadership key: {}", key, ex);
          return false;

        } finally {
          // transactions unset the watch but we also have a get() call before the
          // transaction so we need to make sure to release that watch just in case
          // something goes wrong between the get parsing and transaction execution.
          String unwatchResult = client.unwatch();
          if (unwatchResult == null || !unwatchResult.equals("OK")) {
            logger.warn("Failure unwatching: {}", unwatchResult);
          }
        }
      }
    } catch (Exception ex) {
      logger.error("Unexpected exception updating leadership key: {}", key, ex);
      return false;
    }
  }