Ejemplo n.º 1
0
 /**
  * Return a control message per an encoded status code
  *
  * @param encoded
  * @return
  */
 static ControlMessage mkMessage(short encoded) {
   for (ControlMessage cm : ControlMessage.values()) {
     if (encoded == cm.code) return cm;
   }
   return null;
 }
Ejemplo n.º 2
0
  /*
   * Each ControlMessage is encoded as: code (<0) ... short(2) Each
   * TaskMessage is encoded as: task (>=0) ... short(2) len ... int(4) payload
   * ... byte[] *
   */
  protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf)
      throws Exception {
    // Make sure that we have received at least a short
    long available = buf.readableBytes();
    // Length of control message is 10.
    // Minimum length of a task message is 6(short taskId, int length).
    if (available < 10) {
      // need more data
      return null;
    }

    Long startTime = null;
    if (isServer) {
      startTime = System.nanoTime();
    }
    try {
      // Mark the current buffer position before reading task/len field
      // because the whole frame might not be in the buffer yet.
      // We will reset the buffer position to the marked position if
      // there's not enough bytes in the buffer.
      buf.markReaderIndex();

      // read the short field
      short code = buf.readShort();
      available -= 2;

      // case 1: Control message
      ControlMessage ctrl_msg = ControlMessage.mkMessage(code);
      if (ctrl_msg != null) {
        if (available < 12) {
          // The time stamp bytes were not received yet - return null.
          buf.resetReaderIndex();
          return null;
        }
        long timeStamp = buf.readLong();
        int clientPort = buf.readInt();
        available -= 12;
        if (ctrl_msg == ControlMessage.EOB_MESSAGE) {

          long interval = System.currentTimeMillis() - timeStamp;
          if (interval > 0) {

            Histogram netTransTime = getTransmitHistogram(channel, clientPort);
            if (netTransTime != null) {
              netTransTime.update(interval);
            }
          }

          recvSpeed.update(Double.valueOf(ControlMessage.encodeLength()));
        }

        return ctrl_msg;
      }

      // case 2: task Message
      short task = code;

      // Make sure that we have received at least an integer (length)
      if (available < 8) {
        // need more data
        buf.resetReaderIndex();

        return null;
      }

      // Read the length field.
      int length = buf.readInt();
      if (length <= 0) {
        LOG.info("Receive one message whose TaskMessage's message length is {}", length);
        return new TaskMessage(task, null);
      }
      int headerLength = buf.readInt();
      if (headerLength <= 0) {
        LOG.info("Receive one message whose TaskMessage's message header length is {}", length);
      }
      // Make sure if there's enough bytes in the buffer.
      available -= 8;
      if (available < length + headerLength) {
        // The whole bytes were not received yet - return null.
        buf.resetReaderIndex();

        return null;
      }

      String component = null;
      String stream = null;
      if (headerLength > 0) {
        ChannelBuffer header = buf.readBytes(headerLength);
        String headerValue = new String(header.array());
        String splits[] = headerValue.split(" ");
        stream = splits[0];
        component = splits[1];
      }

      // There's enough bytes in the buffer. Read it.
      ChannelBuffer payload = buf.readBytes(length);

      // Successfully decoded a frame.
      // Return a TaskMessage object

      byte[] rawBytes = payload.array();
      // @@@ TESTING CODE
      // LOG.info("Receive task:{}, length: {}, data:{}",
      // task, length, JStormUtils.toPrintableString(rawBytes));

      TaskMessage ret = new TaskMessage(task, rawBytes, component, stream);
      recvSpeed.update(Double.valueOf(rawBytes.length + 6));
      return ret;
    } finally {
      if (isServer) {
        Long endTime = System.nanoTime();
        timer.update((endTime - startTime) / 1000000.0d);
      }
    }
  }