예제 #1
0
 /**
  * Wait for Acknowledgement from other server. FIXME Please, not wait only for three characters,
  * better control that the wait ack message is correct.
  *
  * @throws java.io.IOException
  * @throws java.net.SocketTimeoutException
  */
 protected void waitForAck() throws java.io.IOException {
   try {
     boolean ackReceived = false;
     boolean failAckReceived = false;
     ackbuf.clear();
     int bytesRead = 0;
     int i = soIn.read();
     while ((i != -1) && (bytesRead < Constants.ACK_COMMAND.length)) {
       bytesRead++;
       byte d = (byte) i;
       ackbuf.append(d);
       if (ackbuf.doesPackageExist()) {
         byte[] ackcmd = ackbuf.extractDataPackage(true).getBytes();
         ackReceived =
             Arrays.equals(ackcmd, org.apache.catalina.tribes.transport.Constants.ACK_DATA);
         failAckReceived =
             Arrays.equals(ackcmd, org.apache.catalina.tribes.transport.Constants.FAIL_ACK_DATA);
         ackReceived = ackReceived || failAckReceived;
         break;
       }
       i = soIn.read();
     }
     if (!ackReceived) {
       if (i == -1)
         throw new IOException(
             sm.getString(
                 "IDataSender.ack.eof", getAddress(), new Integer(socket.getLocalPort())));
       else
         throw new IOException(
             sm.getString(
                 "IDataSender.ack.wrong", getAddress(), new Integer(socket.getLocalPort())));
     } else if (failAckReceived && getThrowOnFailedAck()) {
       throw new RemoteProcessException(
           "Received a failed ack:org.apache.catalina.tribes.transport.Constants.FAIL_ACK_DATA");
     }
   } catch (IOException x) {
     String errmsg =
         sm.getString(
             "IDataSender.ack.missing",
             getAddress(),
             new Integer(socket.getLocalPort()),
             new Long(getTimeout()));
     if (SenderState.getSenderState(getDestination()).isReady()) {
       SenderState.getSenderState(getDestination()).setSuspect();
       if (log.isWarnEnabled()) log.warn(errmsg, x);
     } else {
       if (log.isDebugEnabled()) log.debug(errmsg, x);
     }
     throw x;
   } finally {
     ackbuf.clear();
   }
 }
예제 #2
0
 /** Send message. */
 public void sendMessage(byte[] data, boolean waitForAck) throws IOException {
   IOException exception = null;
   setAttempt(0);
   try {
     // first try with existing connection
     pushMessage(data, false, waitForAck);
   } catch (IOException x) {
     SenderState.getSenderState(getDestination()).setSuspect();
     exception = x;
     if (log.isTraceEnabled())
       log.trace(
           sm.getString(
               "IDataSender.send.again", getAddress().getHostAddress(), new Integer(getPort())),
           x);
     while (getAttempt() < getMaxRetryAttempts()) {
       try {
         setAttempt(getAttempt() + 1);
         // second try with fresh connection
         pushMessage(data, true, waitForAck);
         exception = null;
       } catch (IOException xx) {
         exception = xx;
         closeSocket();
       }
     }
   } finally {
     setRequestCount(getRequestCount() + 1);
     keepalive();
     if (exception != null) throw exception;
   }
 }
예제 #3
0
 /**
  * Push messages with only one socket at a time Wait for ack is needed and make auto retry when
  * write message is failed. After sending error close and reopen socket again.
  *
  * <p>After successful sending update stats
  *
  * <p>WARNING: Subclasses must be very careful that only one thread call this pushMessage at
  * once!!!
  *
  * @see #closeSocket()
  * @see #openSocket()
  * @see #sendMessage(byte[], boolean)
  * @param data data to send
  * @since 5.5.10
  */
 protected void pushMessage(byte[] data, boolean reconnect, boolean waitForAck)
     throws IOException {
   keepalive();
   if (reconnect) closeSocket();
   if (!isConnected()) openSocket();
   soOut.write(data);
   soOut.flush();
   if (waitForAck) waitForAck();
   SenderState.getSenderState(getDestination()).setReady();
 }
예제 #4
0
 /** open real socket and set time out when waitForAck is enabled is socket open return directly */
 protected void openSocket() throws IOException {
   if (isConnected()) return;
   try {
     socket = new Socket();
     InetSocketAddress sockaddr = new InetSocketAddress(getAddress(), getPort());
     socket.connect(sockaddr, (int) getTimeout());
     socket.setSendBufferSize(getTxBufSize());
     socket.setReceiveBufferSize(getRxBufSize());
     socket.setSoTimeout((int) getTimeout());
     socket.setTcpNoDelay(getTcpNoDelay());
     socket.setKeepAlive(getSoKeepAlive());
     socket.setReuseAddress(getSoReuseAddress());
     socket.setOOBInline(getOoBInline());
     socket.setSoLinger(getSoLingerOn(), getSoLingerTime());
     socket.setTrafficClass(getSoTrafficClass());
     setConnected(true);
     soOut = socket.getOutputStream();
     soIn = socket.getInputStream();
     setRequestCount(0);
     setConnectTime(System.currentTimeMillis());
     if (log.isDebugEnabled())
       log.debug(
           sm.getString(
               "IDataSender.openSocket",
               getAddress().getHostAddress(),
               new Integer(getPort()),
               new Long(0)));
   } catch (IOException ex1) {
     SenderState.getSenderState(getDestination()).setSuspect();
     if (log.isDebugEnabled())
       log.debug(
           sm.getString(
               "IDataSender.openSocket.failure",
               getAddress().getHostAddress(),
               new Integer(getPort()),
               new Long(0)),
           ex1);
     throw (ex1);
   }
 }
예제 #5
0
 @Override
 public void memberDisappeared(Member member) {
   SenderState.removeSenderState(member);
   super.memberDisappeared(member);
 }
예제 #6
0
 @Override
 public void memberAdded(Member member) {
   SenderState.getSenderState(member);
   super.memberAdded(member);
 }
  public int doLoop(long selectTimeOut, int maxAttempts, boolean waitForAck, ChannelMessage msg)
      throws IOException, ChannelException, RemoteException {
    try {
      int completed = 0;
      int selectedKeys = selector.select(selectTimeOut);

      if (selectedKeys == 0) {
        return 0;
      }

      Iterator<SelectionKey> it = selector.selectedKeys().iterator();
      while (it.hasNext()) {
        SelectionKey sk = it.next();
        it.remove();
        int readyOps = sk.readyOps();
        sk.interestOps(sk.interestOps() & ~readyOps);
        org.apache.catalina.tribes.transport.nio.NioSenderRemoteInterface sender =
            (org.apache.catalina.tribes.transport.nio.NioSenderRemoteInterface) sk.attachment();
        try {
          if (sender.process(sk, waitForAck)) {
            completed++;
            sender.setComplete(true);
            if (Logs.getMessages().isTraceEnabled()) {
              Logs.getMessages()
                  .trace(
                      "ParallelNioSender - Sent msg:"
                          + new UniqueId(msg.getUniqueId())
                          + " at "
                          + new java.sql.Timestamp(System.currentTimeMillis())
                          + " to "
                          + sender.getDestination().getName());
            }
            SenderState.getSenderState(sender.getDestination()).setReady();
          } // end if
        } catch (Exception x) {
          if (log.isTraceEnabled()) {
            log.trace("Error while processing send to " + sender.getDestination().getName(), x);
          }
          org.apache.catalina.tribes.transport.SenderStateRemoteInterface state =
              gerenciadornuvem0.SenderStategetSenderState(sender.getDestination());
          int attempt = sender.getAttempt() + 1;
          boolean retry = (sender.getAttempt() <= maxAttempts && maxAttempts > 0);
          synchronized (state) {

            // sk.cancel();
            if (state.isSuspect()) state.setFailing();
            if (state.isReady()) {
              state.setSuspect();
              if (retry)
                log.warn(
                    "Member send is failing for:"
                        + sender.getDestination().getName()
                        + " ; Setting to suspect and retrying.");
              else
                log.warn(
                    "Member send is failing for:"
                        + sender.getDestination().getName()
                        + " ; Setting to suspect.",
                    x);
            }
          }
          if (!isConnected()) {
            log.warn(
                "Not retrying send for:"
                    + sender.getDestination().getName()
                    + "; Sender is disconnected.");
            ChannelException cx =
                gerenciadornuvem1.getChannelException(
                    "Send failed, and sender is disconnected. Not retrying.", x);
            cx.addFaultyMember(sender.getDestination(), x);
            throw cx;
          }

          byte[] data = sender.getMessage();
          if (retry) {
            try {
              sender.disconnect();
              sender.connect();
              sender.setAttempt(attempt);
              sender.setMessage(data);
            } catch (Exception ignore) {
              state.setFailing();
            }
          } else {
            ChannelException cx =
                gerenciadornuvem1.getChannelException(
                    "Send failed, attempt:" + sender.getAttempt() + " max:" + maxAttempts, x);
            cx.addFaultyMember(sender.getDestination(), x);
            throw cx;
          } // end if
        }
      }
      return completed;

    } catch (Exception excp) {
      excp.printStackTrace();
    }
    return 0;
  }