@Override
public void dispatchFromOutputChannel(Envelope envelope) throws IOException, InterruptedException {
EnvelopeReceiverList receiverList = getReceiverListForEnvelope(envelope, true);
Buffer srcBuffer = envelope.getBuffer();
Buffer destBuffer = null;
boolean success = false;
try {
if (receiverList.hasLocalReceiver()) {
ChannelID receiver = receiverList.getLocalReceiver();
Channel channel = this.channels.get(receiver);
if (channel == null) {
throw new LocalReceiverCancelledException(receiver);
}
if (!channel.isInputChannel()) {
throw new IOException("Local receiver " + receiver + " is not an input channel.");
}
InputChannel<?> inputChannel = (InputChannel<?>) channel;
// copy the buffer into the memory space of the receiver
if (srcBuffer != null) {
try {
destBuffer = inputChannel.requestBufferBlocking(srcBuffer.size());
} catch (InterruptedException e) {
throw new IOException(e.getMessage());
}
srcBuffer.copyToBuffer(destBuffer);
envelope.setBuffer(destBuffer);
srcBuffer.recycleBuffer();
}
inputChannel.queueEnvelope(envelope);
success = true;
}
else if (receiverList.hasRemoteReceiver()) {
RemoteReceiver remoteReceiver = receiverList.getRemoteReceiver();
// Generate sender hint before sending the first envelope over the network
if (envelope.getSequenceNumber() == 0) {
generateSenderHint(envelope, remoteReceiver);
}
this.nettyConnectionManager.enqueue(envelope, remoteReceiver);
success = true;
}
} finally {
if (!success) {
if (srcBuffer != null) {
srcBuffer.recycleBuffer();
}
if (destBuffer != null) {
destBuffer.recycleBuffer();
}
}
}
}