Search in sources :

Example 1 with CircularBlockingQueue

use of org.apache.zookeeper.util.CircularBlockingQueue in project zookeeper by apache.

the class QuorumCnxManager method handleConnection.

private void handleConnection(Socket sock, DataInputStream din) throws IOException {
    Long sid = null, protocolVersion = null;
    MultipleAddresses electionAddr = null;
    try {
        protocolVersion = din.readLong();
        if (protocolVersion >= 0) {
            // this is a server id and not a protocol version
            sid = protocolVersion;
        } else {
            try {
                InitialMessage init = InitialMessage.parse(protocolVersion, din);
                sid = init.sid;
                if (!init.electionAddr.isEmpty()) {
                    electionAddr = new MultipleAddresses(init.electionAddr, Duration.ofMillis(self.getMultiAddressReachabilityCheckTimeoutMs()));
                }
                LOG.debug("Initial message parsed by {}: {}", self.getId(), init.toString());
            } catch (InitialMessage.InitialMessageException ex) {
                LOG.error("Initial message parsing error!", ex);
                closeSocket(sock);
                return;
            }
        }
        if (sid == QuorumPeer.OBSERVER_ID) {
            /*
                 * Choose identifier at random. We need a value to identify
                 * the connection.
                 */
            sid = observerCounter.getAndDecrement();
            LOG.info("Setting arbitrary identifier to observer: {}", sid);
        }
    } catch (IOException e) {
        LOG.warn("Exception reading or writing challenge", e);
        closeSocket(sock);
        return;
    }
    // do authenticating learner
    authServer.authenticate(sock, din);
    // If wins the challenge, then close the new connection.
    if (sid < self.getId()) {
        /*
             * This replica might still believe that the connection to sid is
             * up, so we have to shut down the workers before trying to open a
             * new connection.
             */
        SendWorker sw = senderWorkerMap.get(sid);
        if (sw != null) {
            sw.finish();
        }
        /*
             * Now we start a new connection
             */
        LOG.debug("Create new connection to server: {}", sid);
        closeSocket(sock);
        if (electionAddr != null) {
            connectOne(sid, electionAddr);
        } else {
            connectOne(sid);
        }
    } else if (sid == self.getId()) {
        // we saw this case in ZOOKEEPER-2164
        LOG.warn("We got a connection request from a server with our own ID. " + "This should be either a configuration error, or a bug.");
    } else {
        // Otherwise start worker threads to receive data.
        SendWorker sw = new SendWorker(sock, sid);
        RecvWorker rw = new RecvWorker(sock, din, sid, sw);
        sw.setRecv(rw);
        SendWorker vsw = senderWorkerMap.get(sid);
        if (vsw != null) {
            vsw.finish();
        }
        senderWorkerMap.put(sid, sw);
        queueSendMap.putIfAbsent(sid, new CircularBlockingQueue<>(SEND_CAPACITY));
        sw.start();
        rw.start();
    }
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) IOException(java.io.IOException) CircularBlockingQueue(org.apache.zookeeper.util.CircularBlockingQueue)

Aggregations

IOException (java.io.IOException)1 AtomicLong (java.util.concurrent.atomic.AtomicLong)1 CircularBlockingQueue (org.apache.zookeeper.util.CircularBlockingQueue)1