@Override public void processResult(int rc, final String path, Object ctx, List<String> children) { KeeperException.Code code = KeeperException.Code.get(rc); _log.debug("{}: getChildren returned {}: {}", new Object[] {path, code, children}); final boolean init = (Boolean) ctx; final String property = getPropertyForPath(path); switch (code) { case OK: if (init) { _zkDataWatcher.initialize(path, children); } else { _zkDataWatcher.processNewChildren(path, children); } break; case NONODE: // The node whose children we are monitoring is gone; set an exists watch on it _log.debug("{}: node is not present, calling exists", path); _zk.exists(path, this, this, false); if (init) { _eventBus.publishInitialize(property, null); _log.debug("{}: published init", path); } else { _eventBus.publishRemove(property); _log.debug("{}: published remove", path); } break; default: _log.error("getChildren: unexpected error: {}: {}", code, path); break; } }
@Override public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) { SplitLogCounters.tot_wkr_get_data_result.incrementAndGet(); if (rc != 0) { LOG.warn("getdata rc = " + KeeperException.Code.get(rc) + " " + path); getDataSetWatchFailure(path); return; } data = watcher.getRecoverableZooKeeper().removeMetaData(data); getDataSetWatchSuccess(path, data); }
// for StatCallback @Override public void processResult(int rc, String path, Object ctx, Stat stat) { KeeperException.Code result = KeeperException.Code.get(rc); if (result != KeeperException.Code.CONNECTIONLOSS) { // reset backoff interval _interval = _initInterval; // subclass should invoke original callback's processResult method here. processStatResult(rc, path, ctx, stat); } else { retryLimitedTimes(); } }
// for VoidCallback @Override public void processResult(int rc, String path, Object ctx) { KeeperException.Code result = KeeperException.Code.get(rc); switch (result) { case CONNECTIONLOSS: retryLimitedTimes(); break; default: // reset backoff interval _interval = _initInterval; processVoidResult(rc, path, ctx); break; } }
@SuppressWarnings({"ThrowableResultOfMethodCallIgnored"}) <DATA_TYPE> void processBackgroundOperation( OperationAndData<DATA_TYPE> operationAndData, CuratorEvent event) { boolean isInitialExecution = (event == null); if (isInitialExecution) { performBackgroundOperation(operationAndData); return; } boolean doQueueOperation = false; do { if (RetryLoop.shouldRetry(event.getResultCode())) { if (client .getRetryPolicy() .allowRetry( operationAndData.getThenIncrementRetryCount(), operationAndData.getElapsedTimeMs(), operationAndData)) { doQueueOperation = true; } else { if (operationAndData.getErrorCallback() != null) { operationAndData.getErrorCallback().retriesExhausted(operationAndData); } KeeperException.Code code = KeeperException.Code.get(event.getResultCode()); Exception e = null; try { e = (code != null) ? KeeperException.create(code) : null; } catch (Throwable ignore) { } if (e == null) { e = new Exception("Unknown result code: " + event.getResultCode()); } logError("Background operation retry gave up", e); } break; } if (operationAndData.getCallback() != null) { sendToBackgroundCallback(operationAndData, event); break; } processEvent(event); } while (false); if (doQueueOperation) { queueOperation(operationAndData); } }
@Override public void processResult(int rc, String path, Object ctx, Stat stat) { KeeperException.Code code = KeeperException.Code.get(rc); _log.debug("{}: exists returned {}", path, code); switch (code) { case OK: // The node is back, get children and set child watch _log.debug("{}: calling getChildren", path); _zk.getChildren(path, this, this, false); break; case NONODE: // The node doesn't exist; OK, the watch is set so now we wait. _log.debug("{}: set exists watch", path); break; default: _log.error("exists: unexpected error: {}: {}", code, path); break; } }
@Override public void processResult(int rawReturnCode, String notUsed, Object parent, String notUsed2) { KeeperException.Code returnCode = KeeperException.Code.get(rawReturnCode); ClaimedCoordinate claimedCoordinate = (ClaimedCoordinate) parent; LOG.fine( "Claim callback with " + returnCode.name() + " " + claimedCoordinate.path + " synched: " + isSynchronizedWithZooKeeper.get() + " thread: " + this); switch (returnCode) { // The claim was successful. This means that the node was created. We need to // populate the status and endpoints. case OK: // We should be the first one to write to the new node, or fail. // This requires that the first version is 0, have not seen this documented // but it should be a fair assumption and is verified by unit tests. synchronized (lastStatusVersionMonitor) { lastStatusVersion = 0; } // We need to set this to synced or updateCoordinateData will complain. // updateCoordinateData will set it to out-of-sync in case of problems. isSynchronizedWithZooKeeper.set(true); try { registerWatcher(); } catch (CloudnameException e) { LOG.fine( "Failed register watcher after claim. Going to state out of sync: " + e.getMessage()); isSynchronizedWithZooKeeper.set(false); return; } catch (InterruptedException e) { LOG.fine("Interrupted while setting up new watcher. Going to state out of sync."); isSynchronizedWithZooKeeper.set(false); return; } // No exceptions, let's celebrate with a log message. LOG.info("Claim processed ok, path: " + path); claimedCoordinate.sendEventToCoordinateListener( CoordinateListener.Event.COORDINATE_OK, "claimed"); return; case NODEEXISTS: // Someone has already claimed the coordinate. It might have been us in a // different thread. If we already have claimed the coordinate then don't care. // Else notify the client. If everything is fine, this is not a true negative, // so ignore it. It might happen if two attempts to tryClaim the coordinate run // in parallel. if (isSynchronizedWithZooKeeper.get() && started.get()) { LOG.fine("Everything is fine, ignoring NODEEXISTS message, path: " + path); return; } LOG.info("Claimed fail, node already exists, will retry: " + path); claimedCoordinate.sendEventToCoordinateListener( CoordinateListener.Event.NOT_OWNER, "Node already exists."); LOG.info("isSynchronizedWithZooKeeper: " + isSynchronizedWithZooKeeper.get()); checkVersion.set(true); return; case NONODE: LOG.info("Could not claim due to missing coordinate, path: " + path); claimedCoordinate.sendEventToCoordinateListener( CoordinateListener.Event.NOT_OWNER, "No node on claiming coordinate: " + returnCode.name()); return; default: // Random problem, report the problem to the client. claimedCoordinate.sendEventToCoordinateListener( CoordinateListener.Event.NO_CONNECTION_TO_STORAGE, "Could not reclaim coordinate. Return code: " + returnCode.name()); return; } }
@Override @SuppressWarnings("unchecked") // this callback could be invoked either in the initial phase or in the normal phase. // The steps of processing result are slightly different between two phases. // - Initial Phase // 1. count down the initialCount // 2. serialize the child data and put it into childMap // 3. if initialCount goes down to 0, meaning we've finished initialization, we call // eventBus#publishInitialize(). Otherwise, we do nothing. // - Normal Phase // 1. serialize the child data and update the childMap // 2. do eventBus#publishAdd() anyway. public void processResult(int rc, String path, Object ctx, byte[] bytes, Stat stat) { KeeperException.Code code = KeeperException.Code.get(rc); _log.debug("{}: getData returned {}", path, code); final String propToPublish = getPropertyToPublish(path); final boolean init = (Boolean) ctx; if (init) _initialCount--; switch (code) { case OK: try { V value = _childSerializer.fromBytes(bytes); _childMap.put(getPropertyForPath(path), value); if (init) { if (_initialCount == 0) { _eventBus.publishInitialize(propToPublish, (T) new HashMap<String, V>(_childMap)); _log.debug("{}: published initialize", propToPublish); } } else { _eventBus.publishAdd(propToPublish, (T) new HashMap<String, V>(_childMap)); _log.debug("{}: published add", propToPublish); } } catch (PropertySerializationException e) { _log.error("Failed to getData for path " + path, e); if (init) { _initialCount = 0; _eventBus.publishInitialize(propToPublish, null); } } break; case NONODE: cancelWatch(getPropertyForPath(path)); _childMap.remove(getPropertyForPath(path)); if (init) { if (_initialCount == 0) { _eventBus.publishInitialize(propToPublish, (T) new HashMap<String, V>(_childMap)); _log.debug("{}: published initialize", propToPublish); } } else { _eventBus.publishAdd(propToPublish, (T) new HashMap<String, V>(_childMap)); _log.debug("{}: published add", propToPublish); } break; default: _log.error("getData: unexpected error: {}: {}", code, path); if (init) { _initialCount = 0; _eventBus.publishInitialize(propToPublish, null); } break; } }
public void processRequest(Request request) { if (LOG.isDebugEnabled()) { LOG.debug("Processing request:: " + request); } // request.addRQRec(">final"); long traceMask = ZooTrace.CLIENT_REQUEST_TRACE_MASK; if (request.type == OpCode.ping) { traceMask = ZooTrace.SERVER_PING_TRACE_MASK; } if (LOG.isTraceEnabled()) { ZooTrace.logRequest(LOG, traceMask, 'E', request, ""); } ProcessTxnResult rc = null; synchronized (zks.outstandingChanges) { while (!zks.outstandingChanges.isEmpty() && zks.outstandingChanges.get(0).zxid <= request.zxid) { ChangeRecord cr = zks.outstandingChanges.remove(0); if (cr.zxid < request.zxid) { LOG.warn("Zxid outstanding " + cr.zxid + " is less than current " + request.zxid); } if (zks.outstandingChangesForPath.get(cr.path) == cr) { zks.outstandingChangesForPath.remove(cr.path); } } if (request.hdr != null) { TxnHeader hdr = request.hdr; Record txn = request.txn; rc = zks.processTxn(hdr, txn); } // do not add non quorum packets to the queue. if (Request.isQuorum(request.type)) { zks.getZKDatabase().addCommittedProposal(request); } } if (request.hdr != null && request.hdr.getType() == OpCode.closeSession) { ServerCnxnFactory scxn = zks.getServerCnxnFactory(); // this might be possible since // we might just be playing diffs from the leader if (scxn != null && request.cnxn == null) { // calling this if we have the cnxn results in the client's // close session response being lost - we've already closed // the session/socket here before we can send the closeSession // in the switch block below scxn.closeSession(request.sessionId); return; } } if (request.cnxn == null) { return; } ServerCnxn cnxn = request.cnxn; String lastOp = "NA"; zks.decInProcess(); Code err = Code.OK; Record rsp = null; boolean closeSession = false; try { if (request.hdr != null && request.hdr.getType() == OpCode.error) { throw KeeperException.create(KeeperException.Code.get(((ErrorTxn) request.txn).getErr())); } KeeperException ke = request.getException(); if (ke != null && request.type != OpCode.multi) { throw ke; } if (LOG.isDebugEnabled()) { LOG.debug("{}", request); } switch (request.type) { case OpCode.ping: { zks.serverStats().updateLatency(request.createTime); lastOp = "PING"; cnxn.updateStatsForResponse( request.cxid, request.zxid, lastOp, request.createTime, System.currentTimeMillis()); cnxn.sendResponse( new ReplyHeader(-2, zks.getZKDatabase().getDataTreeLastProcessedZxid(), 0), null, "response"); return; } case OpCode.createSession: { zks.serverStats().updateLatency(request.createTime); lastOp = "SESS"; cnxn.updateStatsForResponse( request.cxid, request.zxid, lastOp, request.createTime, System.currentTimeMillis()); zks.finishSessionInit(request.cnxn, true); return; } case OpCode.multi: { lastOp = "MULT"; rsp = new MultiResponse(); for (ProcessTxnResult subTxnResult : rc.multiResult) { OpResult subResult; switch (subTxnResult.type) { case OpCode.check: subResult = new CheckResult(); break; case OpCode.create: subResult = new CreateResult(subTxnResult.path); break; case OpCode.delete: subResult = new DeleteResult(); break; case OpCode.setData: subResult = new SetDataResult(subTxnResult.stat); break; case OpCode.error: subResult = new ErrorResult(subTxnResult.err); break; default: throw new IOException("Invalid type of op"); } ((MultiResponse) rsp).add(subResult); } break; } case OpCode.create: { lastOp = "CREA"; rsp = new CreateResponse(rc.path); err = Code.get(rc.err); break; } case OpCode.delete: { lastOp = "DELE"; err = Code.get(rc.err); break; } case OpCode.setData: { lastOp = "SETD"; rsp = new SetDataResponse(rc.stat); err = Code.get(rc.err); break; } case OpCode.setACL: { lastOp = "SETA"; rsp = new SetACLResponse(rc.stat); err = Code.get(rc.err); break; } case OpCode.closeSession: { lastOp = "CLOS"; closeSession = true; err = Code.get(rc.err); break; } case OpCode.sync: { lastOp = "SYNC"; SyncRequest syncRequest = new SyncRequest(); ByteBufferInputStream.byteBuffer2Record(request.request, syncRequest); rsp = new SyncResponse(syncRequest.getPath()); break; } case OpCode.check: { lastOp = "CHEC"; rsp = new SetDataResponse(rc.stat); err = Code.get(rc.err); break; } case OpCode.exists: { lastOp = "EXIS"; // TODO we need to figure out the security requirement for this! ExistsRequest existsRequest = new ExistsRequest(); ByteBufferInputStream.byteBuffer2Record(request.request, existsRequest); String path = existsRequest.getPath(); if (path.indexOf('\0') != -1) { throw new KeeperException.BadArgumentsException(); } Stat stat = zks.getZKDatabase().statNode(path, existsRequest.getWatch() ? cnxn : null); rsp = new ExistsResponse(stat); break; } case OpCode.getData: { lastOp = "GETD"; GetDataRequest getDataRequest = new GetDataRequest(); ByteBufferInputStream.byteBuffer2Record(request.request, getDataRequest); DataNode n = zks.getZKDatabase().getNode(getDataRequest.getPath()); if (n == null) { throw new KeeperException.NoNodeException(); } Long aclL; synchronized (n) { aclL = n.acl; } PrepRequestProcessor.checkACL( zks, zks.getZKDatabase().convertLong(aclL), ZooDefs.Perms.READ, request.authInfo); Stat stat = new Stat(); byte b[] = zks.getZKDatabase() .getData( getDataRequest.getPath(), stat, getDataRequest.getWatch() ? cnxn : null); rsp = new GetDataResponse(b, stat); break; } case OpCode.setWatches: { lastOp = "SETW"; SetWatches setWatches = new SetWatches(); // XXX We really should NOT need this!!!! request.request.rewind(); ByteBufferInputStream.byteBuffer2Record(request.request, setWatches); long relativeZxid = setWatches.getRelativeZxid(); zks.getZKDatabase() .setWatches( relativeZxid, setWatches.getDataWatches(), setWatches.getExistWatches(), setWatches.getChildWatches(), cnxn); break; } case OpCode.getACL: { lastOp = "GETA"; GetACLRequest getACLRequest = new GetACLRequest(); ByteBufferInputStream.byteBuffer2Record(request.request, getACLRequest); Stat stat = new Stat(); List<ACL> acl = zks.getZKDatabase().getACL(getACLRequest.getPath(), stat); rsp = new GetACLResponse(acl, stat); break; } case OpCode.getChildren: { lastOp = "GETC"; GetChildrenRequest getChildrenRequest = new GetChildrenRequest(); ByteBufferInputStream.byteBuffer2Record(request.request, getChildrenRequest); DataNode n = zks.getZKDatabase().getNode(getChildrenRequest.getPath()); if (n == null) { throw new KeeperException.NoNodeException(); } Long aclG; synchronized (n) { aclG = n.acl; } PrepRequestProcessor.checkACL( zks, zks.getZKDatabase().convertLong(aclG), ZooDefs.Perms.READ, request.authInfo); List<String> children = zks.getZKDatabase() .getChildren( getChildrenRequest.getPath(), null, getChildrenRequest.getWatch() ? cnxn : null); rsp = new GetChildrenResponse(children); break; } case OpCode.getChildren2: { lastOp = "GETC"; GetChildren2Request getChildren2Request = new GetChildren2Request(); ByteBufferInputStream.byteBuffer2Record(request.request, getChildren2Request); Stat stat = new Stat(); DataNode n = zks.getZKDatabase().getNode(getChildren2Request.getPath()); if (n == null) { throw new KeeperException.NoNodeException(); } Long aclG; synchronized (n) { aclG = n.acl; } PrepRequestProcessor.checkACL( zks, zks.getZKDatabase().convertLong(aclG), ZooDefs.Perms.READ, request.authInfo); List<String> children = zks.getZKDatabase() .getChildren( getChildren2Request.getPath(), stat, getChildren2Request.getWatch() ? cnxn : null); rsp = new GetChildren2Response(children, stat); break; } } } catch (SessionMovedException e) { // session moved is a connection level error, we need to tear // down the connection otw ZOOKEEPER-710 might happen // ie client on slow follower starts to renew session, fails // before this completes, then tries the fast follower (leader) // and is successful, however the initial renew is then // successfully fwd/processed by the leader and as a result // the client and leader disagree on where the client is most // recently attached (and therefore invalid SESSION MOVED generated) cnxn.sendCloseSession(); return; } catch (KeeperException e) { err = e.code(); } catch (Exception e) { // log at error level as we are returning a marshalling // error to the user LOG.error("Failed to process " + request, e); StringBuilder sb = new StringBuilder(); ByteBuffer bb = request.request; bb.rewind(); while (bb.hasRemaining()) { sb.append(Integer.toHexString(bb.get() & 0xff)); } LOG.error("Dumping request buffer: 0x" + sb.toString()); err = Code.MARSHALLINGERROR; } long lastZxid = zks.getZKDatabase().getDataTreeLastProcessedZxid(); ReplyHeader hdr = new ReplyHeader(request.cxid, lastZxid, err.intValue()); zks.serverStats().updateLatency(request.createTime); cnxn.updateStatsForResponse( request.cxid, lastZxid, lastOp, request.createTime, System.currentTimeMillis()); try { cnxn.sendResponse(hdr, rsp, "response"); if (closeSession) { cnxn.sendCloseSession(); } } catch (IOException e) { LOG.error("FIXMSG", e); } }