use of org.apache.zookeeper.WatchedEvent in project hbase by apache.
the class HBaseTestingUtility method expireSession.
/**
* Expire a ZooKeeper session as recommended in ZooKeeper documentation
* http://hbase.apache.org/book.html#trouble.zookeeper
* There are issues when doing this:
* [1] http://www.mail-archive.com/dev@zookeeper.apache.org/msg01942.html
* [2] https://issues.apache.org/jira/browse/ZOOKEEPER-1105
*
* @param nodeZK - the ZK watcher to expire
* @param checkStatus - true to check if we can create an HTable with the
* current configuration.
*/
public void expireSession(ZooKeeperWatcher nodeZK, boolean checkStatus) throws Exception {
Configuration c = new Configuration(this.conf);
String quorumServers = ZKConfig.getZKQuorumServersString(c);
ZooKeeper zk = nodeZK.getRecoverableZooKeeper().getZooKeeper();
byte[] password = zk.getSessionPasswd();
long sessionID = zk.getSessionId();
// Expiry seems to be asynchronous (see comment from P. Hunt in [1]),
// so we create a first watcher to be sure that the
// event was sent. We expect that if our watcher receives the event
// other watchers on the same machine will get is as well.
// When we ask to close the connection, ZK does not close it before
// we receive all the events, so don't have to capture the event, just
// closing the connection should be enough.
ZooKeeper monitor = new ZooKeeper(quorumServers, 1000, new org.apache.zookeeper.Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
LOG.info("Monitor ZKW received event=" + watchedEvent);
}
}, sessionID, password);
// Making it expire
ZooKeeper newZK = new ZooKeeper(quorumServers, 1000, EmptyWatcher.instance, sessionID, password);
//ensure that we have connection to the server before closing down, otherwise
//the close session event will be eaten out before we start CONNECTING state
long start = System.currentTimeMillis();
while (newZK.getState() != States.CONNECTED && System.currentTimeMillis() - start < 1000) {
Thread.sleep(1);
}
newZK.close();
LOG.info("ZK Closed Session 0x" + Long.toHexString(sessionID));
// Now closing & waiting to be sure that the clients get it.
monitor.close();
if (checkStatus) {
getConnection().getTable(TableName.META_TABLE_NAME).close();
}
}
use of org.apache.zookeeper.WatchedEvent in project weave by continuuity.
the class KillZKSession method kill.
/**
* Kills a Zookeeper client to simulate failure scenarious during testing.
* Callee will provide the amount of time to wait before it's considered failure
* to kill a client.
*
* @param client that needs to be killed.
* @param connectionString of Quorum
* @param maxMs time in millisecond specifying the max time to kill a client.
* @throws IOException When there is IO error
* @throws InterruptedException When call has been interrupted.
*/
public static void kill(ZooKeeper client, String connectionString, int maxMs) throws IOException, InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
ZooKeeper zk = new ZooKeeper(connectionString, maxMs, new Watcher() {
@Override
public void process(WatchedEvent event) {
if (event.getState() == Event.KeeperState.SyncConnected) {
latch.countDown();
}
}
}, client.getSessionId(), client.getSessionPasswd());
try {
Preconditions.checkState(latch.await(maxMs, TimeUnit.MILLISECONDS), "Fail to kill ZK connection.");
} finally {
zk.close();
}
}
use of org.apache.zookeeper.WatchedEvent in project weave by continuuity.
the class ZKClientTest method testExpireRewatch.
@Test
public void testExpireRewatch() throws InterruptedException, IOException, ExecutionException {
InMemoryZKServer zkServer = InMemoryZKServer.builder().setTickTime(1000).build();
zkServer.startAndWait();
try {
final CountDownLatch expireReconnectLatch = new CountDownLatch(1);
final AtomicBoolean expired = new AtomicBoolean(false);
final ZKClientService client = ZKClientServices.delegate(ZKClients.reWatchOnExpire(ZKClientService.Builder.of(zkServer.getConnectionStr()).setSessionTimeout(2000).setConnectionWatcher(new Watcher() {
@Override
public void process(WatchedEvent event) {
if (event.getState() == Event.KeeperState.Expired) {
expired.set(true);
} else if (event.getState() == Event.KeeperState.SyncConnected && expired.compareAndSet(true, true)) {
expireReconnectLatch.countDown();
}
}
}).build()));
client.startAndWait();
try {
final BlockingQueue<Watcher.Event.EventType> events = new LinkedBlockingQueue<Watcher.Event.EventType>();
client.exists("/expireRewatch", new Watcher() {
@Override
public void process(WatchedEvent event) {
client.exists("/expireRewatch", this);
events.add(event.getType());
}
});
client.create("/expireRewatch", null, CreateMode.PERSISTENT);
Assert.assertEquals(Watcher.Event.EventType.NodeCreated, events.poll(2, TimeUnit.SECONDS));
KillZKSession.kill(client.getZooKeeperSupplier().get(), zkServer.getConnectionStr(), 1000);
Assert.assertTrue(expireReconnectLatch.await(5, TimeUnit.SECONDS));
client.delete("/expireRewatch");
Assert.assertEquals(Watcher.Event.EventType.NodeDeleted, events.poll(4, TimeUnit.SECONDS));
} finally {
client.stopAndWait();
}
} finally {
zkServer.stopAndWait();
}
}
use of org.apache.zookeeper.WatchedEvent in project hadoop by apache.
the class TestActiveStandbyElector method testSuccessiveStandbyCalls.
/**
* verify becomeStandby is not called if already in standby
*/
@Test
public void testSuccessiveStandbyCalls() {
elector.joinElection(data);
// make the object go into the monitoring standby state
elector.processResult(Code.NODEEXISTS.intValue(), ZK_LOCK_NAME, mockZK, ZK_LOCK_NAME);
Mockito.verify(mockApp, Mockito.times(1)).becomeStandby();
verifyExistCall(1);
Assert.assertTrue(elector.isMonitorLockNodePending());
Stat stat = new Stat();
stat.setEphemeralOwner(0L);
Mockito.when(mockZK.getSessionId()).thenReturn(1L);
elector.processResult(Code.OK.intValue(), ZK_LOCK_NAME, mockZK, stat);
Assert.assertFalse(elector.isMonitorLockNodePending());
WatchedEvent mockEvent = Mockito.mock(WatchedEvent.class);
Mockito.when(mockEvent.getPath()).thenReturn(ZK_LOCK_NAME);
// notify node deletion
// monitoring should be setup again after event is received
Mockito.when(mockEvent.getType()).thenReturn(Event.EventType.NodeDeleted);
elector.processWatchEvent(mockZK, mockEvent);
// is standby. no need to notify anything now
Mockito.verify(mockApp, Mockito.times(0)).enterNeutralMode();
// another joinElection called.
Mockito.verify(mockZK, Mockito.times(2)).create(ZK_LOCK_NAME, data, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL, elector, mockZK);
// lost election
elector.processResult(Code.NODEEXISTS.intValue(), ZK_LOCK_NAME, mockZK, ZK_LOCK_NAME);
// still standby. so no need to notify again
Mockito.verify(mockApp, Mockito.times(1)).becomeStandby();
// monitor is set again
verifyExistCall(2);
}
use of org.apache.zookeeper.WatchedEvent in project druid by druid-io.
the class LoadQueuePeon method processSegmentChangeRequest.
private void processSegmentChangeRequest() {
if (currentlyProcessing == null) {
if (!segmentsToDrop.isEmpty()) {
currentlyProcessing = segmentsToDrop.firstEntry().getValue();
log.info("Server[%s] dropping [%s]", basePath, currentlyProcessing.getSegmentIdentifier());
} else if (!segmentsToLoad.isEmpty()) {
currentlyProcessing = segmentsToLoad.firstEntry().getValue();
log.info("Server[%s] loading [%s]", basePath, currentlyProcessing.getSegmentIdentifier());
} else {
return;
}
try {
if (currentlyProcessing == null) {
if (!stopped) {
log.makeAlert("Crazy race condition! server[%s]", basePath).emit();
}
actionCompleted();
return;
}
log.info("Server[%s] processing segment[%s]", basePath, currentlyProcessing.getSegmentIdentifier());
final String path = ZKPaths.makePath(basePath, currentlyProcessing.getSegmentIdentifier());
final byte[] payload = jsonMapper.writeValueAsBytes(currentlyProcessing.getChangeRequest());
curator.create().withMode(CreateMode.EPHEMERAL).forPath(path, payload);
processingExecutor.schedule(new Runnable() {
@Override
public void run() {
try {
if (curator.checkExists().forPath(path) != null) {
failAssign(new ISE("%s was never removed! Failing this operation!", path));
}
} catch (Exception e) {
failAssign(e);
}
}
}, config.getLoadTimeoutDelay().getMillis(), TimeUnit.MILLISECONDS);
final Stat stat = curator.checkExists().usingWatcher(new CuratorWatcher() {
@Override
public void process(WatchedEvent watchedEvent) throws Exception {
switch(watchedEvent.getType()) {
case NodeDeleted:
entryRemoved(watchedEvent.getPath());
}
}
}).forPath(path);
if (stat == null) {
final byte[] noopPayload = jsonMapper.writeValueAsBytes(new SegmentChangeRequestNoop());
// Create a node and then delete it to remove the registered watcher. This is a work-around for
// a zookeeper race condition. Specifically, when you set a watcher, it fires on the next event
// that happens for that node. If no events happen, the watcher stays registered foreverz.
// Couple that with the fact that you cannot set a watcher when you create a node, but what we
// want is to create a node and then watch for it to get deleted. The solution is that you *can*
// set a watcher when you check to see if it exists so, we first create the node and then set a
// watcher on its existence. However, if already does not exist by the time the existence check
// returns, then the watcher that was set will never fire (nobody will ever create the node
// again) and thus lead to a slow, but real, memory leak. So, we create another node to cause
// that watcher to fire and delete it right away.
//
// We do not create the existence watcher first, because then it will fire when we create the
// node and we'll have the same race when trying to refresh that watcher.
curator.create().withMode(CreateMode.EPHEMERAL).forPath(path, noopPayload);
entryRemoved(path);
}
} catch (Exception e) {
failAssign(e);
}
} else {
log.info("Server[%s] skipping doNext() because something is currently loading[%s].", basePath, currentlyProcessing.getSegmentIdentifier());
}
}
Aggregations