@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);
 }
Example #3
0
 // 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();
   }
 }
Example #4
0
 // 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;
   }
 }
Example #5
0
  @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);
    }
  }