synchronized boolean finish() {
      if (LOG.isDebugEnabled()) {
        LOG.debug("Calling finish for " + sid);
      }

      if (!running) {
        /*
         * Avoids running finish() twice.
         */
        return running;
      }

      running = false;
      closeSocket(sock);
      // channel = null;

      this.interrupt();
      if (recvWorker != null) {
        recvWorker.finish();
      }

      if (LOG.isDebugEnabled()) {
        LOG.debug("Removing entry from senderWorkerMap sid=" + sid);
      }
      senderWorkerMap.remove(sid, this);
      threadCnt.decrementAndGet();
      return running;
    }
  /**
   * If this server has initiated the connection, then it gives up on the connection if it loses
   * challenge. Otherwise, it keeps the connection.
   */
  public boolean initiateConnection(Socket sock, Long sid) {
    DataOutputStream dout = null;
    try {
      // Sending id and challenge
      dout = new DataOutputStream(sock.getOutputStream());
      dout.writeLong(self.getId());
      dout.flush();
    } catch (IOException e) {
      LOG.warn("Ignoring exception reading or writing challenge: ", e);
      closeSocket(sock);
      return false;
    }

    // If lost the challenge, then drop the new connection
    if (sid > self.getId()) {
      LOG.info(
          "Have smaller server identifier, so dropping the "
              + "connection: ("
              + sid
              + ", "
              + self.getId()
              + ")");
      closeSocket(sock);
      // Otherwise proceed with the connection
    } else {
      SendWorker sw = new SendWorker(sock, sid);
      RecvWorker rw = new RecvWorker(sock, sid, sw);
      sw.setRecv(rw);

      SendWorker vsw = senderWorkerMap.get(sid);

      if (vsw != null) vsw.finish();

      senderWorkerMap.put(sid, sw);
      if (!queueSendMap.containsKey(sid)) {
        queueSendMap.put(sid, new ArrayBlockingQueue<ByteBuffer>(SEND_CAPACITY));
      }

      sw.start();
      rw.start();

      return true;
    }
    return false;
  }
Esempio n. 3
0
  public Connection(String host, int port) {
    server_port = port;
    server_addr = host;

    packets = new LinkedList<Packet>();

    recv_worker = new RecvWorker();
    recv_worker.start();
  }
Esempio n. 4
0
 public void Close() {
   recv_worker.interrupt();
 }
  /**
   * If this server receives a connection request, then it gives up on the new connection if it
   * wins. Notice that it checks whether it has a connection to this server already or not. If it
   * does, then it sends the smallest possible long value to lose the challenge.
   */
  public boolean receiveConnection(Socket sock) {
    Long sid = null;

    try {
      // Read server id
      DataInputStream din = new DataInputStream(sock.getInputStream());
      sid = din.readLong();
      if (sid == QuorumPeer.OBSERVER_ID) {
        /*
         * Choose identifier at random. We need a value to identify
         * the connection.
         */

        sid = observerCounter--;
        LOG.info("Setting arbitrary identifier to observer: " + sid);
      }
    } catch (IOException e) {
      closeSocket(sock);
      LOG.warn("Exception reading or writing challenge: " + e.toString());
      return false;
    }

    // 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);
      connectOne(sid);

      // Otherwise start worker threads to receive data.
    } else {
      SendWorker sw = new SendWorker(sock, sid);
      RecvWorker rw = new RecvWorker(sock, sid, sw);
      sw.setRecv(rw);

      SendWorker vsw = senderWorkerMap.get(sid);

      if (vsw != null) vsw.finish();

      senderWorkerMap.put(sid, sw);

      if (!queueSendMap.containsKey(sid)) {
        queueSendMap.put(sid, new ArrayBlockingQueue<ByteBuffer>(SEND_CAPACITY));
      }

      sw.start();
      rw.start();

      return true;
    }
    return false;
  }
  /*
   * 读取对方的sid
   */
  public boolean receiveConnection(Socket sock) {
    Long sid = null;

    try {
      // Read server id
      DataInputStream din = new DataInputStream(sock.getInputStream());
      sid = din.readLong();
      if (sid < 0) { // this is not a server id but a protocol version
        // (see ZOOKEEPER-1633)
        sid = din.readLong();
        // next comes the #bytes in the remainder of the message
        int num_remaining_bytes = din.readInt();
        byte[] b = new byte[num_remaining_bytes];
        // remove the remainder of the message from din
        int num_read = din.read(b);
        if (num_read != num_remaining_bytes) {
          LOG.error(
              "Read only "
                  + num_read
                  + " bytes out of "
                  + num_remaining_bytes
                  + " sent by server "
                  + sid);
        }
      }
      if (sid == QuorumPeer.OBSERVER_ID) {
        /*
         * Choose identifier at random. We need a value to identify the
         * connection.
         */

        sid = observerCounter--;
        LOG.info("Setting arbitrary identifier to observer: " + sid);
      }
    } catch (IOException e) {
      closeSocket(sock);
      LOG.warn("Exception reading or writing challenge: " + e.toString());
      return false;
    }

    // If wins the challenge, then close the new connection.
    /*
     * 只允许sid大的连接小的
     */
    if (sid < self.getId()) {
      /*
       * This replica might still believe that the connection to sid is
       * up, so we have to shut down the workers be fore 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);
      connectOne(sid);

      // Otherwise start worker threads to receive data.
    } else {
      SendWorker sw = new SendWorker(sock, sid);
      RecvWorker rw = new RecvWorker(sock, sid, sw);
      sw.setRecv(rw);

      SendWorker vsw = senderWorkerMap.get(sid);

      if (vsw != null) vsw.finish();

      senderWorkerMap.put(sid, sw);

      if (!queueSendMap.containsKey(sid)) {
        queueSendMap.put(sid, new ArrayBlockingQueue<ByteBuffer>(SEND_CAPACITY));
      }

      sw.start();
      rw.start();

      return true;
    }
    return false;
  }