}
}
// Pick the channel for this scope
int idx = (Integer.MAX_VALUE & destination.getScope().hashCode()) % channels.size();
Channel channel = channels.get(idx);
if (channel == null || !channel.isOpen() || isExpired(channel)) {
synchronized (channelMap) {
channel = channels.get(idx);
if (channel == null || !channel.isOpen() || isExpired(channel)) {
if (channel != null && channel.isOpen()) {
channel.close();
}
channel = clientBootstrap.connect(destination.getSocketAddress()).sync().channel();
channels.set(idx, channel);
statChannelOpen.inc();
channelOpenTimes.put(channel, System.currentTimeMillis());
}
}
}
// Compute total length
int headerLength =
NUM_LENGTH_FIELDS
* (Integer.SIZE / 8)
+ (Integer.SIZE / 8)
* 2 // version, type
+ (Long.SIZE / 8)
* 2 // 128 bit UUID
+ getLength(destination.getScope().getCluster())
+ getLength(destination.getScope().getResource())
+ getLength(destination.getScope().getPartition())
+ getLength(destination.getScope().getState()) + getLength(config.getInstanceName())
+ getLength(destination.getInstanceName());
int messageLength = message == null ? 0 : message.readableBytes();
// Build message header
ByteBuf headerBuf = channel.alloc().buffer(headerLength);
headerBuf.writeInt(MESSAGE_VERSION).writeInt(messageType)
.writeLong(messageId.getMostSignificantBits())
.writeLong(messageId.getLeastSignificantBits());
writeStringWithLength(headerBuf, destination.getScope().getCluster());
writeStringWithLength(headerBuf, destination.getScope().getResource());
writeStringWithLength(headerBuf, destination.getScope().getPartition());
writeStringWithLength(headerBuf, destination.getScope().getState());
writeStringWithLength(headerBuf, config.getInstanceName());
writeStringWithLength(headerBuf, destination.getInstanceName());
// Compose message header and payload
headerBuf.writeInt(messageLength);
CompositeByteBuf fullByteBuf = channel.alloc().compositeBuffer(2);
fullByteBuf.addComponent(headerBuf);
fullByteBuf.writerIndex(headerBuf.readableBytes());
if (message != null) {
fullByteBuf.addComponent(message);
fullByteBuf.writerIndex(fullByteBuf.writerIndex() + message.readableBytes());
}
// Send
statTxMsg.mark();
statTxBytes.mark(fullByteBuf.readableBytes());
channel.writeAndFlush(fullByteBuf);
} catch (Exception e) {
statError.inc();
throw new IllegalStateException("Could not send message to " + destination, e);
}
}