package edu.uw.zookeeper.protocol.client; import edu.uw.zookeeper.common.Automaton; import edu.uw.zookeeper.common.Pair; import edu.uw.zookeeper.net.Connection; import edu.uw.zookeeper.protocol.Operation; import edu.uw.zookeeper.protocol.ZxidReference; public class ZxidTracker implements ZxidReference { public static class ZxidListener extends Pair<ZxidTracker,Connection<?,?,?>> implements Connection.Listener<Object> { public ZxidListener(ZxidTracker tracker, Connection<?,?,?> connection) { super(tracker, connection); second().subscribe(this); } public void handleSessionReply(Operation.ProtocolResponse<?> message) { first().update(message.zxid()); } @Override public void handleConnectionState(Automaton.Transition<Connection.State> state) { if (state.to() == Connection.State.CONNECTION_CLOSED) { second().unsubscribe(this); } } @Override public void handleConnectionRead(Object message) { if (message instanceof Operation.ResponseId) { first().update(((Operation.ResponseId) message).zxid()); } } } public static ZxidTracker zero() { return forZxid(0L); } public static ZxidTracker forZxid(long lastZxid) { return new ZxidTracker(lastZxid); } public static ZxidListener listener(ZxidTracker tracker, Connection<?,?,?> connection) { return new ZxidListener(tracker, connection); } protected volatile long maxZxid; protected ZxidTracker(long lastZxid) { super(); this.maxZxid = lastZxid; } @Override public long get() { return maxZxid; } public synchronized long update(long zxid) { if (maxZxid < zxid) { maxZxid = zxid; } return maxZxid; } }