Package com.xiaomi.infra.chronos

Source Code of com.xiaomi.infra.chronos.ChronosServerWatcher

package com.xiaomi.infra.chronos;

import java.io.IOException;
import java.util.Arrays;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;

import com.xiaomi.infra.chronos.exception.FatalChronosException;
import com.xiaomi.infra.chronos.exception.ChronosException;
import com.xiaomi.infra.chronos.zookeeper.FailoverWatcher;
import com.xiaomi.infra.chronos.zookeeper.ZooKeeperUtil;

/**
* The ZooKeeper watcher for ChronosServer provides the interface to get the persistent timestamp
* which is the max value allocated currently.
*/
public class ChronosServerWatcher extends FailoverWatcher {
  private static final Log LOG = LogFactory.getLog(ChronosServerWatcher.class);

  private final String persistentTimestampZnode;
  private boolean beenActiveMaster = false;
  private long persistentTimestamp;

  /**
   * Construct ChronosServerWatcher with properties.
   *
   * @param properties the properties of ChronosServerWatcher
   * @param canInitZnode whether it can create znode or not
   * @throws IOException when it's error to construct ZooKeeper watcher
   */
  public ChronosServerWatcher(Properties properties, boolean canInitZnode) throws IOException {
    super(properties, canInitZnode);
   
    persistentTimestampZnode = baseZnode + "/persistent-timestamp";
  }

  /**
   * Construct ChronosServerWatcher with properties.
   *
   * @param properties the properties of ChronosServerWatcher
   * @throws IOException when it's error to construct ZooKeeper watcher
   */
  public ChronosServerWatcher(Properties properties) throws IOException {
    this(properties, true);
  }

  /**
   * Create the base znode of chronos.
   */
  @Override
  protected void initZnode() {
    try {
      ZooKeeperUtil.createAndFailSilent(this, "/chronos");
      super.initZnode();
      ZooKeeperUtil.createAndFailSilent(this, baseZnode + "/persistent-timestamp");
    } catch (Exception e) {
      LOG.fatal("Error to create znode of chronos, exit immediately");
      System.exit(0);
    }
  }

  /**
   * Get persistent timestamp in ZooKeeper with retries.
   *
   * @return the persistent timestamp in ZooKeeper
   * @throws ChronosException error to get data from ZooKeeper after retrying
   */
  public long getPersistentTimestamp() throws ChronosException {
    byte[] persistentTimesampBytes = null;
    for (int i = 0; i <= connectRetryTimes; ++i) {
      try {
        persistentTimesampBytes = ZooKeeperUtil.getDataAndWatch(this, persistentTimestampZnode);
        break;
      } catch (KeeperException e) {
        if (i == connectRetryTimes) {
          throw new ChronosException(
              "Can't get persistent timestamp from ZooKeeper after retrying", e);
        }
        LOG.info("Exception to get persistent timestamp from ZooKeeper, retry " + (i + 1) + " times");
      }
    }

    if (Arrays.equals(persistentTimesampBytes, new byte[0])) {
      persistentTimestamp = 0; // for the very first time
    } else {
      persistentTimestamp = ZooKeeperUtil.bytesToLong(persistentTimesampBytes);
    }

    if (LOG.isDebugEnabled()) {
      LOG.debug("Return persistent timestamp " + persistentTimestamp + " to timestamp server");
    }
    return persistentTimestamp;
  }

  /**
   * Get the cached timestamp in ChronosServerWatcher.
   *
   * @return the local persistentTimestamp
   */
  public long getCachedPersistentTimestamp() {
    return persistentTimestamp;
  }

  /**
   * Set persistent timestamp in ZooKeeper.
   *
   * @param newTimestamp the new value to set
   * @throws FatalChronosException if try to set a small value
   * @throws ChronosException if error to set value in ZooKeeper
   */
  public void setPersistentTimestamp(long newTimestamp) throws FatalChronosException,
      ChronosException {
    if (newTimestamp <= persistentTimestamp) {
      throw new FatalChronosException("Fatal error to set a smaller timestamp");
    }

    if (LOG.isDebugEnabled()) {
      LOG.debug("Setting persistent timestamp " + newTimestamp + " in ZooKeeper");
    }

    for (int i = 0; i <= connectRetryTimes; ++i) {
      try {
        ZooKeeperUtil.setData(this, persistentTimestampZnode, ZooKeeperUtil.longToBytes(newTimestamp));
        persistentTimestamp = newTimestamp;
        break;
      } catch (KeeperException e) {
        if (i == connectRetryTimes) {
          throw new ChronosException(
              "Error to set persistent timestamp in ZooKeeper after retrying", e);
        }
        LOG.info("Exception to set persistent timestamp in ZooKeeper, retry " + (i + 1) + " times");
      }
    }
  }

  /**
   * Deal with the connection event.
   *
   * @param event the ZooKeeper event.
   */
  @Override
  protected void processConnection(WatchedEvent event) {
    super.processConnection(event);
    switch (event.getState()) {
    case Disconnected:
      if (beenActiveMaster) {
        LOG.fatal(hostPort.getHostPort()
            + " disconnected from ZooKeeper, stop serving and exit immediately");
        System.exit(0);
      } else {
        LOG.warn(hostPort.getHostPort()
            + " disconnected from ZooKeeper, wait to sync and try to become active master");
      }
      break;
    default:
      break;
    }
  }

  public String getPersistentTimestampZnode(){
    return persistentTimestampZnode;
  }
 
  public void setBeenActiveMaster(boolean beenActiveMaster) {
    this.beenActiveMaster = beenActiveMaster;
  }
 
}
TOP

Related Classes of com.xiaomi.infra.chronos.ChronosServerWatcher

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.