/** * Release the tryClaim of the coordinate. It means that nobody owns the coordinate anymore. * Requires that that this instance owns the tryClaim to the coordinate. */ public void releaseClaim() throws CloudnameException { scheduler.shutdown(); zkClient.deregisterListener(this); while (true) { final TrackedConfig config; synchronized (trackedConfigList) { if (trackedConfigList.isEmpty()) { break; } config = trackedConfigList.remove(0); } config.stop(); } sendEventToCoordinateListener( CoordinateListener.Event.NOT_OWNER, "Released claim of coordinate"); synchronized (lastStatusVersionMonitor) { try { zkClient.getZookeeper().delete(path, lastStatusVersion); } catch (InterruptedException e) { throw new CloudnameException(e); } catch (KeeperException e) { throw new CloudnameException(e); } } }
/** * Creates the serialized value of the object and stores this in ZooKeeper under the path. It * updates the lastStatusVersion. It does not set a watcher for the path. */ private void updateCoordinateData() throws CoordinateMissingException, CloudnameException { if (!started.get()) { throw new IllegalStateException("Not started."); } if (!zkClient.isConnected()) { throw new CloudnameException("No proper connection with zookeeper."); } synchronized (lastStatusVersionMonitor) { try { Stat stat = zkClient .getZookeeper() .setData( path, zkCoordinateData.snapshot().serialize().getBytes(Util.CHARSET_NAME), lastStatusVersion); LOG.fine("Updated coordinate, latest version is " + stat.getVersion()); lastStatusVersion = stat.getVersion(); } catch (KeeperException.NoNodeException e) { throw new CoordinateMissingException("Coordinate does not exist " + path); } catch (KeeperException e) { throw new CloudnameException( "ZooKeeper errror in updateCoordinateData: " + e.getMessage(), e); } catch (UnsupportedEncodingException e) { throw new CloudnameException(e); } catch (InterruptedException e) { throw new CloudnameException(e); } catch (IOException e) { throw new CloudnameException(e); } } }
/** Register a watcher for the coordinate. */ private void registerWatcher() throws CloudnameException, InterruptedException { LOG.fine("Register watcher for ZooKeeper.."); try { zkClient.getZookeeper().exists(path, this); } catch (KeeperException e) { throw new CloudnameException(e); } }
/** * Claims a coordinate. To know if it was successful or not you need to register a listener. * * @return this. */ public ClaimedCoordinate start() { zkClient.registerListener(this); started.set(true); final long periodicDelayMs = 2000; scheduler.scheduleWithFixedDelay( new ResolveProblems(), 1 /* initial delay ms */, periodicDelayMs, TimeUnit.MILLISECONDS); return this; }
private void tryClaim() { try { zkClient .getZookeeper() .create( path, zkCoordinateData.snapshot().serialize().getBytes(Util.CHARSET_NAME), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL, new ClaimCallback(), this); } catch (IOException e) { LOG.info("Got IO exception on claim with new ZooKeeper instance " + e.getMessage()); } }
/** * Handles event from ZooKeeper for this coordinate. * * @param event */ @Override public void process(WatchedEvent event) { LOG.info("Got an event from ZooKeeper " + event.toString()); synchronized (lastStatusVersionMonitor) { switch (event.getType()) { case None: switch (event.getState()) { case SyncConnected: break; case Disconnected: case AuthFailed: case Expired: default: // If we lost connection, we don't attempt to register another watcher as // this might be blocking forever. Parent will try to reconnect (reclaim) // later. isSynchronizedWithZooKeeper.set(false); sendEventToCoordinateListener( CoordinateListener.Event.NO_CONNECTION_TO_STORAGE, event.toString()); return; } return; case NodeDeleted: // If node is deleted, we have no node to place a new watcher so we stop watching. isSynchronizedWithZooKeeper.set(false); sendEventToCoordinateListener(CoordinateListener.Event.NOT_OWNER, event.toString()); return; case NodeDataChanged: LOG.fine("Node data changed, check versions."); boolean verifiedSynchronized = false; try { final Stat stat = zkClient.getZookeeper().exists(path, this); if (stat == null) { LOG.info("Could not stat path, setting out of synch, will retry claim"); } else { LOG.fine("Previous version is " + lastStatusVersion + " now is " + stat.getVersion()); if (stat.getVersion() != lastStatusVersion) { LOG.fine("Version mismatch, sending out of sync."); } else { verifiedSynchronized = true; } } } catch (KeeperException e) { LOG.fine( "Problems with zookeeper, sending consistencyState out of sync: " + e.getMessage()); } catch (InterruptedException e) { LOG.fine("Got interrupted: " + e.getMessage()); return; } finally { isSynchronizedWithZooKeeper.set(verifiedSynchronized); } if (verifiedSynchronized) { sendEventToCoordinateListener( CoordinateListener.Event.COORDINATE_OUT_OF_SYNC, event.toString()); } return; case NodeChildrenChanged: case NodeCreated: // This should not happen.. isSynchronizedWithZooKeeper.set(false); sendEventToCoordinateListener( CoordinateListener.Event.COORDINATE_OUT_OF_SYNC, event.toString()); return; } } }
public CloudnameLock getCloudnameLock(CloudnameLock.Scope scope, String lockName) { return new ZkCloudnameLock(zkClient.getZookeeper(), coordinate, scope, lockName); }