Java tutorial
/* * arcus-java-client : Arcus Java client * Copyright 2010-2014 NAVER Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.spy.memcached; import java.util.List; import net.spy.memcached.compat.SpyObject; import org.apache.zookeeper.AsyncCallback.ChildrenCallback; import org.apache.zookeeper.KeeperException.Code; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; /** * CacheMonitor monitors the changes of the cache server list * in the ZooKeeper node(/arcus/cache_list/<service_code>). */ public class CacheMonitor extends SpyObject implements Watcher, ChildrenCallback { ZooKeeper zk; String cacheListZPath; String serviceCode; volatile boolean dead; CacheMonitorListener listener; /** * Constructor * * @param zk * ZooKeeper connection * @param serviceCode * service code (or cloud name) to identify each cloud * @param listener * Callback listener */ public CacheMonitor(ZooKeeper zk, String cacheListZPath, String serviceCode, CacheMonitorListener listener) { this.zk = zk; this.cacheListZPath = cacheListZPath; this.serviceCode = serviceCode; this.listener = listener; getLogger().info("Initializing the CacheMonitor."); // Get the cache list from the Arcus admin asynchronously. // Returning list would be processed in processResult(). asyncGetCacheList(); } /** * Other classes use the CacheMonitor by implementing this method */ public interface CacheMonitorListener { /** * The existing children of the node has changed. */ void commandNodeChange(List<String> children); List<String> getPrevChildren(); /** * The ZooKeeper session is no longer valid. */ void closing(); } /** * Processes every events from the ZooKeeper. */ public void process(WatchedEvent event) { if (event.getType() == Event.EventType.None) { // Processes session events switch (event.getState()) { case SyncConnected: getLogger().warn("Reconnected to the Arcus admin. " + getInfo()); return; case Disconnected: getLogger().warn("Disconnected from the Arcus admin. Trying to reconnect. " + getInfo()); return; case Expired: // If the session was expired, just shutdown this client to be re-initiated. getLogger().warn("Session expired. Trying to reconnect to the Arcus admin." + getInfo()); shutdown(); return; } } else { // Set a new watch on the znode when there are any changes in it. if (event.getType() == Event.EventType.NodeChildrenChanged) { asyncGetCacheList(); } } } /** * A callback function to process the result of getChildren(watch=true). */ public void processResult(int rc, String path, Object ctx, List<String> children) { switch (Code.get(rc)) { case OK: listener.commandNodeChange(children); return; case NONODE: getLogger().fatal("Cannot find your service code. Please contact Arcus support to solve this problem. " + getInfo()); return; case SESSIONEXPIRED: getLogger().warn("Session expired. Trying to reconnect to the Arcus admin. " + getInfo()); shutdown(); return; case NOAUTH: getLogger().fatal("Authorization failed " + getInfo()); shutdown(); return; case CONNECTIONLOSS: getLogger().warn("Connection lost. Trying to reconnect to the Arcus admin." + getInfo()); asyncGetCacheList(); return; default: getLogger().warn( "Ignoring an unexpected event from the Arcus admin. code=" + Code.get(rc) + ", " + getInfo()); asyncGetCacheList(); return; } } /** * Get the cache list asynchronously from the Arcus admin. */ void asyncGetCacheList() { if (getLogger().isDebugEnabled()) { getLogger().debug("Set a new watch on " + (cacheListZPath + serviceCode)); } zk.getChildren(cacheListZPath + serviceCode, true, this, null); } /** * Shutdown the CacheMonitor. */ public void shutdown() { getLogger().info("Shutting down the CacheMonitor. " + getInfo()); dead = true; listener.closing(); } private String getInfo() { String zkSessionId = null; if (zk != null) { zkSessionId = "0x" + Long.toHexString(zk.getSessionId()); } return "[serviceCode=" + serviceCode + ", adminSessionId=" + zkSessionId + "]"; } }