@Override public void process(WatchedEvent event) { if (delegate != null && event.getType() != Event.EventType.None) { try { delegate.process(event); } catch (Throwable t) { LOG.error("Watcher throws exception.", t); } } if (event.getState() != Event.KeeperState.Expired) { return; } switch (actionType) { case EXISTS: exists(); break; case CHILDREN: children(); break; case DATA: data(); break; } }
@Override public void onSuccess(Stat result) { wrappedWatcher.setLastResult(result); }
@Override public void onSuccess(NodeData result) { Object oldResult = lastResult.getReference(); lastResult.compareAndSet(oldResult, null, true, false); if (!result.equals(oldResult)) { // Whenever something changed, treated it as data changed. process(new WatchedEvent(Event.EventType.NodeDataChanged, Event.KeeperState.SyncConnected, path)); } }
@Override public OperationFuture<NodeChildren> getChildren(String path, Watcher watcher) { if (watcher == null) { return super.getChildren(path, null); } final RewatchOnExpireWatcher wrappedWatcher = new RewatchOnExpireWatcher(this, ActionType.CHILDREN, path, watcher); OperationFuture<NodeChildren> result = super.getChildren(path, wrappedWatcher); Futures.addCallback(result, new FutureCallback<NodeChildren>() { @Override public void onSuccess(NodeChildren result) { wrappedWatcher.setLastResult(result); } @Override public void onFailure(Throwable t) { // No-op } }); return result; }
@Override public void onSuccess(NodeData result) { Object oldResult = lastResult.getReference(); lastResult.compareAndSet(oldResult, null, true, false); if (!result.equals(oldResult)) { // Whenever something changed, treated it as data changed. process(new WatchedEvent(Event.EventType.NodeDataChanged, Event.KeeperState.SyncConnected, path)); } }
@Override public OperationFuture<NodeChildren> getChildren(String path, Watcher watcher) { if (watcher == null) { return super.getChildren(path, null); } final RewatchOnExpireWatcher wrappedWatcher = new RewatchOnExpireWatcher(this, ActionType.CHILDREN, path, watcher); OperationFuture<NodeChildren> result = super.getChildren(path, wrappedWatcher); Futures.addCallback(result, new FutureCallback<NodeChildren>() { @Override public void onSuccess(NodeChildren result) { wrappedWatcher.setLastResult(result); } @Override public void onFailure(Throwable t) { // No-op } }); return result; }
@Override public void process(WatchedEvent event) { if (delegate != null && event.getType() != Event.EventType.None) { try { delegate.process(event); } catch (Throwable t) { LOG.error("Watcher throws exception.", t); } } if (event.getState() != Event.KeeperState.Expired) { return; } switch (actionType) { case EXISTS: exists(); break; case CHILDREN: children(); break; case DATA: data(); break; } }
@Override public void onSuccess(Stat stat) { // Since we know all callbacks and watcher are triggered from single event thread, there is no race condition. Object oldResult = lastResult.getReference(); lastResult.compareAndSet(oldResult, null, true, false); if (stat != oldResult && (stat == null || !stat.equals(oldResult))) { if (stat == null) { // previous stat is not null, means node deleted process(new WatchedEvent(Event.EventType.NodeDeleted, Event.KeeperState.SyncConnected, path)); } else if (oldResult == null) { // previous stat is null, means node created process(new WatchedEvent(Event.EventType.NodeCreated, Event.KeeperState.SyncConnected, path)); } else { // Otherwise, something changed on the node process(new WatchedEvent(Event.EventType.NodeDataChanged, Event.KeeperState.SyncConnected, path)); } } }
@Override public void onSuccess(NodeData result) { wrappedWatcher.setLastResult(result); }
@Override public OperationFuture<NodeData> getData(String path, Watcher watcher) { if (watcher == null) { return super.getData(path, null); } final RewatchOnExpireWatcher wrappedWatcher = new RewatchOnExpireWatcher(this, ActionType.DATA, path, watcher); OperationFuture<NodeData> result = super.getData(path, wrappedWatcher); Futures.addCallback(result, new FutureCallback<NodeData>() { @Override public void onSuccess(NodeData result) { wrappedWatcher.setLastResult(result); } @Override public void onFailure(Throwable t) { // No-op } }); return result; } }
@Override public void onSuccess(Stat stat) { // Since we know all callbacks and watcher are triggered from single event thread, there is no race condition. Object oldResult = lastResult.getReference(); lastResult.compareAndSet(oldResult, null, true, false); if (stat != oldResult && (stat == null || !stat.equals(oldResult))) { if (stat == null) { // previous stat is not null, means node deleted process(new WatchedEvent(Event.EventType.NodeDeleted, Event.KeeperState.SyncConnected, path)); } else if (oldResult == null) { // previous stat is null, means node created process(new WatchedEvent(Event.EventType.NodeCreated, Event.KeeperState.SyncConnected, path)); } else { // Otherwise, something changed on the node process(new WatchedEvent(Event.EventType.NodeDataChanged, Event.KeeperState.SyncConnected, path)); } } }
@Override public void onSuccess(Stat result) { wrappedWatcher.setLastResult(result); }
@Override public OperationFuture<Stat> exists(String path, Watcher watcher) { if (watcher == null) { return super.exists(path, null); } final RewatchOnExpireWatcher wrappedWatcher = new RewatchOnExpireWatcher(this, ActionType.EXISTS, path, watcher); OperationFuture<Stat> result = super.exists(path, wrappedWatcher); Futures.addCallback(result, new FutureCallback<Stat>() { @Override public void onSuccess(Stat result) { wrappedWatcher.setLastResult(result); } @Override public void onFailure(Throwable t) { // No-op } }); return result; }
@Override public void onSuccess(NodeChildren result) { Object oldResult = lastResult.getReference(); lastResult.compareAndSet(oldResult, null, true, false); if (result.equals(oldResult)) { return; } if (!(oldResult instanceof NodeChildren)) { // Something very wrong LOG.error("The same watcher has been used for different event type."); return; } NodeChildren oldNodeChildren = (NodeChildren) oldResult; if (!result.getChildren().equals(oldNodeChildren.getChildren())) { process(new WatchedEvent(Event.EventType.NodeChildrenChanged, Event.KeeperState.SyncConnected, path)); } else { process(new WatchedEvent(Event.EventType.NodeDataChanged, Event.KeeperState.SyncConnected, path)); } }
@Override public void onSuccess(NodeChildren result) { wrappedWatcher.setLastResult(result); }
@Override public OperationFuture<NodeData> getData(String path, Watcher watcher) { if (watcher == null) { return super.getData(path, null); } final RewatchOnExpireWatcher wrappedWatcher = new RewatchOnExpireWatcher(this, ActionType.DATA, path, watcher); OperationFuture<NodeData> result = super.getData(path, wrappedWatcher); Futures.addCallback(result, new FutureCallback<NodeData>() { @Override public void onSuccess(NodeData result) { wrappedWatcher.setLastResult(result); } @Override public void onFailure(Throwable t) { // No-op } }); return result; } }
@Override public void onSuccess(NodeChildren result) { Object oldResult = lastResult.getReference(); lastResult.compareAndSet(oldResult, null, true, false); if (result.equals(oldResult)) { return; } if (!(oldResult instanceof NodeChildren)) { // Something very wrong LOG.error("The same watcher has been used for different event type."); return; } NodeChildren oldNodeChildren = (NodeChildren) oldResult; if (!result.getChildren().equals(oldNodeChildren.getChildren())) { process(new WatchedEvent(Event.EventType.NodeChildrenChanged, Event.KeeperState.SyncConnected, path)); } else { process(new WatchedEvent(Event.EventType.NodeDataChanged, Event.KeeperState.SyncConnected, path)); } }
@Override public void onSuccess(NodeData result) { wrappedWatcher.setLastResult(result); }
@Override public OperationFuture<Stat> exists(String path, Watcher watcher) { if (watcher == null) { return super.exists(path, null); } final RewatchOnExpireWatcher wrappedWatcher = new RewatchOnExpireWatcher(this, ActionType.EXISTS, path, watcher); OperationFuture<Stat> result = super.exists(path, wrappedWatcher); Futures.addCallback(result, new FutureCallback<Stat>() { @Override public void onSuccess(Stat result) { wrappedWatcher.setLastResult(result); } @Override public void onFailure(Throwable t) { // No-op } }); return result; }
@Override public void onFailure(Throwable t) { if (RetryUtils.canRetry(t)) { data(); return; } lastResult.set(null, false); if (t instanceof KeeperException) { KeeperException.Code code = ((KeeperException) t).code(); if (code == KeeperException.Code.NONODE) { // Node deleted process(new WatchedEvent(Event.EventType.NodeDeleted, Event.KeeperState.SyncConnected, path)); return; } } LOG.error("Fail to re-set watch on getData for path " + path, t); } });