use of org.apache.storm.messaging.TaskMessage in project storm by apache.
the class Client method send.
/**
* Enqueue task messages to be sent to the remote destination (cf. `host` and `port`).
*/
@Override
public void send(Iterator<TaskMessage> msgs) {
if (closing) {
int numMessages = iteratorSize(msgs);
LOG.error("Dropping {} messages because the Netty client to {} is being closed", numMessages, dstAddressPrefixedName);
return;
}
if (!hasMessages(msgs)) {
return;
}
Channel channel = getConnectedChannel();
if (channel == null) {
/*
* Connection is unavailable. We will drop pending messages and let at-least-once message replay kick in.
*
* Another option would be to buffer the messages in memory. But this option has the risk of causing OOM errors,
* especially for topologies that disable message acking because we don't know whether the connection recovery will
* succeed or not, and how long the recovery will take.
*/
dropMessages(msgs);
return;
}
try {
while (msgs.hasNext()) {
TaskMessage message = msgs.next();
MessageBatch batch = batcher.add(message);
if (batch != null) {
writeMessage(channel, batch);
}
}
MessageBatch batch = batcher.drain();
if (batch != null) {
writeMessage(channel, batch);
}
} catch (IOException e) {
LOG.warn("Exception when sending message to remote worker.", e);
dropMessages(msgs);
}
}
use of org.apache.storm.messaging.TaskMessage in project storm by apache.
the class Server method sendLoadMetrics.
@Override
public void sendLoadMetrics(Map<Integer, Double> taskToLoad) {
MessageBatch mb = new MessageBatch(1);
synchronized (ser) {
mb.add(new TaskMessage(LOAD_METRICS_TASK_ID, ser.serialize(Collections.singletonList((Object) taskToLoad))));
}
allChannels.writeAndFlush(mb);
}
use of org.apache.storm.messaging.TaskMessage in project storm by apache.
the class MessageDecoder method decode.
/*
* Each ControlMessage is encoded as:
* code (<0) ... short(2)
* Each TaskMessage is encoded as:
* task (>=0) ... short(2)
* len ... int(4)
* payload ... byte[] *
*/
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf buf, List<Object> out) throws Exception {
// Make sure that we have received at least a short
long available = buf.readableBytes();
if (available < 2) {
// need more data
return;
}
List<Object> ret = new ArrayList<>();
// Use while loop, try to decode as more messages as possible in single call
while (available >= 2) {
// 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 controlMessage = ControlMessage.mkMessage(code);
if (controlMessage != null) {
if (controlMessage == ControlMessage.EOB_MESSAGE) {
continue;
} else {
out.add(controlMessage);
return;
}
}
// case 2: SaslTokenMessageRequest
if (code == SaslMessageToken.IDENTIFIER) {
// Make sure that we have received at least an integer (length)
if (buf.readableBytes() < 4) {
// need more data
buf.resetReaderIndex();
return;
}
// Read the length field.
int length = buf.readInt();
if (length <= 0) {
out.add(new SaslMessageToken(null));
return;
}
// Make sure if there's enough bytes in the buffer.
if (buf.readableBytes() < length) {
// The whole bytes were not received yet - return null.
buf.resetReaderIndex();
return;
}
// There's enough bytes in the buffer. Read it.
byte[] bytes = new byte[length];
buf.readBytes(bytes);
// Successfully decoded a frame.
// Return a SaslTokenMessageRequest object
out.add(new SaslMessageToken(bytes));
return;
}
// case 3: BackPressureStatus
if (code == BackPressureStatus.IDENTIFIER) {
available = buf.readableBytes();
if (available < 4) {
// Need more data
buf.resetReaderIndex();
return;
}
int dataLen = buf.readInt();
if (available < 4 + dataLen) {
// need more data
buf.resetReaderIndex();
return;
}
byte[] bytes = new byte[dataLen];
buf.readBytes(bytes);
out.add(BackPressureStatus.read(bytes, deser));
return;
}
// Make sure that we have received at least an integer (length)
if (available < 4) {
// need more data
buf.resetReaderIndex();
break;
}
// Read the length field.
int length = buf.readInt();
available -= 4;
if (length <= 0) {
ret.add(new TaskMessage(code, null));
break;
}
// Make sure if there's enough bytes in the buffer.
if (available < length) {
// The whole bytes were not received yet - return null.
buf.resetReaderIndex();
break;
}
available -= length;
// There's enough bytes in the buffer. Read it.
byte[] bytes = new byte[length];
buf.readBytes(bytes);
// Successfully decoded a frame.
// Return a TaskMessage object
ret.add(new TaskMessage(code, bytes));
}
if (!ret.isEmpty()) {
out.add(ret);
}
}
Aggregations