Example #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();
   }
 }
  /**
   * @param destination Member[] - destination.length &gt; 0
   * @param msg Serializable - the message to send
   * @param options sender options, options can trigger guarantee levels and different interceptors
   *     to react to the message see class documentation for the <code>Channel</code> object.<br>
   * @param handler - callback object for error handling and completion notification, used when a
   *     message is sent asynchronously using the <code>Channel.SEND_OPTIONS_ASYNCHRONOUS</code>
   *     flag enabled.
   * @return UniqueId - the unique Id that was assigned to this message
   * @throws ChannelException - if an error occurs processing the message
   * @see org.apache.catalina.tribes.Channel
   */
  @Override
  public UniqueId send(Member[] destination, Serializable msg, int options, ErrorHandler handler)
      throws ChannelException {
    if (msg == null) throw new ChannelException(sm.getString("groupChannel.nullMessage"));
    XByteBuffer buffer = null;
    try {
      if (destination == null || destination.length == 0) {
        throw new ChannelException(sm.getString("groupChannel.noDestination"));
      }
      ChannelData data = new ChannelData(true); // generates a unique Id
      data.setAddress(getLocalMember(false));
      data.setTimestamp(System.currentTimeMillis());
      byte[] b = null;
      if (msg instanceof ByteMessage) {
        b = ((ByteMessage) msg).getMessage();
        options = options | SEND_OPTIONS_BYTE_MESSAGE;
      } else {
        b = XByteBuffer.serialize(msg);
        options = options & (~SEND_OPTIONS_BYTE_MESSAGE);
      }
      data.setOptions(options);
      // XByteBuffer buffer = new XByteBuffer(b.length+128,false);
      buffer = BufferPool.getBufferPool().getBuffer(b.length + 128, false);
      buffer.append(b, 0, b.length);
      data.setMessage(buffer);
      InterceptorPayload payload = null;
      if (handler != null) {
        payload = new InterceptorPayload();
        payload.setErrorHandler(handler);
      }
      getFirstInterceptor().sendMessage(destination, data, payload);
      if (Logs.MESSAGES.isTraceEnabled()) {
        Logs.MESSAGES.trace(
            "GroupChannel - Sent msg:"
                + new UniqueId(data.getUniqueId())
                + " at "
                + new java.sql.Timestamp(System.currentTimeMillis())
                + " to "
                + Arrays.toNameString(destination));
        Logs.MESSAGES.trace(
            "GroupChannel - Send Message:" + new UniqueId(data.getUniqueId()) + " is " + msg);
      }

      return new UniqueId(data.getUniqueId());
    } catch (Exception x) {
      if (x instanceof ChannelException) throw (ChannelException) x;
      throw new ChannelException(x);
    } finally {
      if (buffer != null) BufferPool.getBufferPool().returnBuffer(buffer);
    }
  }
Example #3
0
  public static void main(String[] args) throws Exception {

    Member mbr = new MemberImpl("localhost", 9999, 0);
    ChannelData data = new ChannelData();
    data.setOptions(Channel.SEND_OPTIONS_BYTE_MESSAGE);
    data.setAddress(mbr);
    byte[] buf = new byte[8192 * 4];
    data.setMessage(new XByteBuffer(buf, false));
    buf = XByteBuffer.createDataPackage(data);
    int len = buf.length;
    System.out.println("Message size:" + len + " bytes");
    BigDecimal total = new BigDecimal((double) 0);
    BigDecimal bytes = new BigDecimal((double) len);
    Socket socket = new Socket("localhost", 9999);
    System.out.println("Writing to 9999");
    OutputStream out = socket.getOutputStream();
    long start = 0;
    double mb = 0;
    boolean first = true;
    int count = 0;
    DecimalFormat df = new DecimalFormat("##.00");
    while (count < 1000000) {
      if (first) {
        first = false;
        start = System.currentTimeMillis();
      }
      out.write(buf, 0, buf.length);
      mb += ((double) buf.length) / 1024 / 1024;
      total = total.add(bytes);
      if (((++count) % 10000) == 0) {
        long time = System.currentTimeMillis();
        double seconds = ((double) (time - start)) / 1000;
        System.out.println(
            "Throughput "
                + df.format(mb / seconds)
                + " MB/seconds messages "
                + count
                + ", total "
                + mb
                + " MB, total "
                + total
                + " bytes.");
      }
    }
    out.flush();
    System.out.println("Complete, sleeping 5 seconds");
    Thread.sleep(5000);
  }
  protected static boolean memberAlive(
      Member mbr,
      byte[] msgData,
      boolean sendTest,
      boolean readTest,
      long readTimeout,
      long conTimeout,
      int optionFlag) {
    // could be a shutdown notification
    if (Arrays.equals(mbr.getCommand(), Member.SHUTDOWN_PAYLOAD)) return false;

    Socket socket = new Socket();
    try {
      InetAddress ia = InetAddress.getByAddress(mbr.getHost());
      InetSocketAddress addr = new InetSocketAddress(ia, mbr.getPort());
      socket.setSoTimeout((int) readTimeout);
      socket.connect(addr, (int) conTimeout);
      if (sendTest) {
        ChannelData data = new ChannelData(true);
        data.setAddress(mbr);
        data.setMessage(new XByteBuffer(msgData, false));
        data.setTimestamp(System.currentTimeMillis());
        int options = optionFlag | Channel.SEND_OPTIONS_BYTE_MESSAGE;
        if (readTest) options = (options | Channel.SEND_OPTIONS_USE_ACK);
        else options = (options & (~Channel.SEND_OPTIONS_USE_ACK));
        data.setOptions(options);
        byte[] message = XByteBuffer.createDataPackage(data);
        socket.getOutputStream().write(message);
        if (readTest) {
          int length = socket.getInputStream().read(message);
          return length > 0;
        }
      } // end if
      return true;
    } catch (SocketTimeoutException sx) {
      // do nothing, we couldn't connect
    } catch (ConnectException cx) {
      // do nothing, we couldn't connect
    } catch (Exception x) {
      log.error("Unable to perform failure detection check, assuming member down.", x);
    } finally {
      try {
        socket.close();
      } catch (Exception ignore) {
      }
    }
    return false;
  }
 @Override
 public void messageReceived(ChannelMessage msg) {
   if (!okToProcess(msg.getOptions())) {
     super.messageReceived(msg);
     return;
   }
   int msgnr =
       XByteBuffer.toInt(msg.getMessage().getBytesDirect(), msg.getMessage().getLength() - 4);
   msg.getMessage().trim(4);
   MessageOrder order = new MessageOrder(msgnr, (ChannelMessage) msg.deepclone());
   try {
     inLock.writeLock().lock();
     if (processIncoming(order)) processLeftOvers(msg.getAddress(), false);
   } finally {
     inLock.writeLock().unlock();
   }
 }
 public static Data createRandomData(int size, int number) {
   int i = r.nextInt();
   i = (i % 127);
   int length = Math.abs(r.nextInt() % size);
   if (length < 100) length += 100;
   Data d = new Data();
   d.length = length;
   d.key = (byte) i;
   d.data = new byte[length];
   Arrays.fill(d.data, d.key);
   if (number > 0 && d.data.length >= 4) {
     // populate number
     d.hasNr = true;
     XByteBuffer.toBytes(number, d.data, 0);
   }
   return d;
 }
Example #7
0
  @Override
  public void broadcast(ChannelMessage message) throws ChannelException {
    if (impl == null || (impl.startLevel & Channel.MBR_TX_SEQ) != Channel.MBR_TX_SEQ)
      throw new ChannelException(sm.getString("mcastService.noStart"));

    byte[] data = XByteBuffer.createDataPackage((ChannelData) message);
    if (data.length > McastServiceImpl.MAX_PACKET_SIZE) {
      throw new ChannelException(
          sm.getString(
              "mcastService.exceed.maxPacketSize",
              Integer.toString(data.length),
              Integer.toString(McastServiceImpl.MAX_PACKET_SIZE)));
    }
    DatagramPacket packet = new DatagramPacket(data, 0, data.length);
    try {
      impl.send(false, packet);
    } catch (Exception x) {
      throw new ChannelException(x);
    }
  }
 public int getNumber() {
   if (!hasNr) return -1;
   return XByteBuffer.toInt(this.data, 0);
 }
  public static void main(String[] args) throws Exception {
    Selector selector = Selector.open();
    Member mbr = new MemberImpl("localhost", 9999, 0);
    ChannelData data = new ChannelData();
    data.setOptions(Channel.SEND_OPTIONS_BYTE_MESSAGE);
    data.setAddress(mbr);
    byte[] buf = new byte[8192 * 4];
    data.setMessage(new XByteBuffer(buf, false));
    buf = XByteBuffer.createDataPackage(data);
    int len = buf.length;
    BigDecimal total = new BigDecimal((double) 0);
    BigDecimal bytes = new BigDecimal((double) len);
    NioSender sender = new NioSender();
    sender.setDestination(mbr);
    sender.setDirectBuffer(true);
    sender.setSelector(selector);
    sender.setTxBufSize(1024 * 1024);
    sender.connect();
    sender.setMessage(buf);
    System.out.println("Writing to 9999");
    long start = 0;
    double mb = 0;
    boolean first = true;
    int count = 0;
    DecimalFormat df = new DecimalFormat("##.00");
    while (count < 100000) {
      if (first) {
        first = false;
        start = System.currentTimeMillis();
      }
      sender.setMessage(buf);
      int selectedKeys = 0;
      try {
        selectedKeys = selector.select(0);
      } catch (Exception e) {
        e.printStackTrace();
        continue;
      }

      if (selectedKeys == 0) {
        continue;
      }

      Iterator it = selector.selectedKeys().iterator();
      while (it.hasNext()) {
        SelectionKey sk = (SelectionKey) it.next();
        it.remove();
        try {
          int readyOps = sk.readyOps();
          sk.interestOps(sk.interestOps() & ~readyOps);
          if (sender.process(sk, false)) {
            total = total.add(bytes);
            sender.reset();
            sender.setMessage(buf);
            mb += ((double) len) / 1024 / 1024;
            if (((++count) % 10000) == 0) {
              long time = System.currentTimeMillis();
              double seconds = ((double) (time - start)) / 1000;
              System.out.println(
                  "Throughput "
                      + df.format(mb / seconds)
                      + " MB/seconds, total "
                      + mb
                      + " MB, total "
                      + total
                      + " bytes.");
            }
          }

        } catch (Throwable t) {
          t.printStackTrace();
          return;
        }
      }
      selector.selectedKeys().clear();
    }
    System.out.println("Complete, sleeping 15 seconds");
    Thread.sleep(15000);
  }
  /**
   * Callback from the interceptor stack. <br>
   * When a message is received from a remote node, this method will be invoked by the previous
   * interceptor.<br>
   * This method can also be used to send a message to other components within the same application,
   * but its an extreme case, and you're probably better off doing that logic between the
   * applications itself.
   *
   * @param msg ChannelMessage
   */
  @Override
  public void messageReceived(ChannelMessage msg) {
    if (msg == null) return;
    try {
      if (Logs.MESSAGES.isTraceEnabled()) {
        Logs.MESSAGES.trace(
            "GroupChannel - Received msg:"
                + new UniqueId(msg.getUniqueId())
                + " at "
                + new java.sql.Timestamp(System.currentTimeMillis())
                + " from "
                + msg.getAddress().getName());
      }

      Serializable fwd = null;
      if ((msg.getOptions() & SEND_OPTIONS_BYTE_MESSAGE) == SEND_OPTIONS_BYTE_MESSAGE) {
        fwd = new ByteMessage(msg.getMessage().getBytes());
      } else {
        try {
          fwd =
              XByteBuffer.deserialize(
                  msg.getMessage().getBytesDirect(), 0, msg.getMessage().getLength());
        } catch (Exception sx) {
          log.error(sm.getString("groupChannel.unable.deserialize", msg), sx);
          return;
        }
      }
      if (Logs.MESSAGES.isTraceEnabled()) {
        Logs.MESSAGES.trace(
            "GroupChannel - Receive Message:" + new UniqueId(msg.getUniqueId()) + " is " + fwd);
      }

      // get the actual member with the correct alive time
      Member source = msg.getAddress();
      boolean rx = false;
      boolean delivered = false;
      for (int i = 0; i < channelListeners.size(); i++) {
        ChannelListener channelListener = (ChannelListener) channelListeners.get(i);
        if (channelListener != null && channelListener.accept(fwd, source)) {
          channelListener.messageReceived(fwd, source);
          delivered = true;
          // if the message was accepted by an RPC channel, that channel
          // is responsible for returning the reply, otherwise we send an absence reply
          if (channelListener instanceof RpcChannel) rx = true;
        }
      } // for
      if ((!rx) && (fwd instanceof RpcMessage)) {
        // if we have a message that requires a response,
        // but none was given, send back an immediate one
        sendNoRpcChannelReply((RpcMessage) fwd, source);
      }
      if (Logs.MESSAGES.isTraceEnabled()) {
        Logs.MESSAGES.trace(
            "GroupChannel delivered[" + delivered + "] id:" + new UniqueId(msg.getUniqueId()));
      }

    } catch (Exception x) {
      // this could be the channel listener throwing an exception, we should log it
      // as a warning.
      if (log.isWarnEnabled()) log.warn(sm.getString("groupChannel.receiving.error"), x);
      throw new RemoteProcessException("Exception:" + x.getMessage(), x);
    }
  }