package io.fathom.cloud.state; import io.fathom.cloud.zookeeper.ZookeeperClient; import java.io.IOException; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.KeeperException.NoNodeException; import org.apache.zookeeper.KeeperException.NodeExistsException; import org.apache.zookeeper.data.Stat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ZookeeperNodeVersionIdProvider implements IdProvider { // See: // http://zookeeper-user.578899.n2.nabble.com/Sequence-Number-Generation-With-Zookeeper-td5378618.html private static final Logger log = LoggerFactory.getLogger(ZookeeperNodeVersionIdProvider.class); final ZookeeperClient client; final String path; public ZookeeperNodeVersionIdProvider(ZookeeperClient client, String path) { super(); this.client = client; this.path = path; } static final byte[] VALUE = new byte[0]; @Override public int get() { boolean autoCreate = true; while (true) { try { try { Stat stat = client.setData(path, VALUE, -1); return stat.getVersion(); } catch (NoNodeException e) { if (autoCreate) { log.info("Node not found; creating: " + path); autoCreate = false; try { client.create(path, VALUE, true); } catch (NodeExistsException e1) { log.info("Node concurrently created: " + path, e1); } } else { throw e; } } } catch (KeeperException e) { throw new IllegalStateException("Error communicating with zookeeper", e); } catch (IOException e) { throw new IllegalStateException("Error communicating with zookeeper", e); } } } }