/**
* Copyright 2014 Ricardo Padilha
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.dsys.snio.impl.group;
import java.io.IOException;
import java.nio.ByteBuffer;
import javax.annotation.Nonnull;
import net.dsys.commons.api.lang.BinaryUnit;
import net.dsys.commons.api.lang.Copier;
import net.dsys.commons.api.lang.Factory;
import net.dsys.commons.impl.lang.ByteBufferCopier;
import net.dsys.commons.impl.lang.ByteBufferFactory;
import net.dsys.snio.api.buffer.MessageBufferConsumer;
import net.dsys.snio.api.channel.MessageChannel;
import net.dsys.snio.api.codec.MessageCodec;
import net.dsys.snio.api.limit.RateLimiter;
import net.dsys.snio.api.pool.SelectorPool;
import net.dsys.snio.impl.buffer.BlockingQueueProvider;
import net.dsys.snio.impl.buffer.RingBufferProvider;
import net.dsys.snio.impl.channel.MessageChannels;
import net.dsys.snio.impl.channel.builder.ChannelConfig;
import net.dsys.snio.impl.channel.builder.ClientConfig;
import net.dsys.snio.impl.group.builder.GroupConfig;
/**
* @author Ricardo Padilha
*/
public final class GroupChannels {
private GroupChannels() {
// no instantiation
return;
}
@Nonnull
public static GroupChannel<ByteBuffer> openTCPGroup(final ChannelConfig<ByteBuffer> common,
final GroupConfig group) throws IOException {
final Factory<MessageCodec> codecs = group.getMessageCodecs();
final Factory<RateLimiter> limiters = group.getRateLimiters();
final Factory<ByteBuffer> factory = new ByteBufferFactory(codecs.newInstance().getBodyLength());
final MessageBufferConsumer<ByteBuffer> consumer;
if (common.isRingBuffer()) {
consumer = RingBufferProvider.createConsumer(common.getCapacity(), factory);
} else {
consumer = BlockingQueueProvider.createConsumer(common.getCapacity(), factory);
}
final Copier<ByteBuffer> copier = new ByteBufferCopier();
final ChannelFactory<ByteBuffer> builder = new ChannelFactory<ByteBuffer>() {
@Override
public MessageChannel<ByteBuffer> open() throws IOException {
final ClientConfig client = new ClientConfig()
.setMessageCodec(codecs.newInstance())
.setRateLimiter(limiters.newInstance());
return MessageChannels.openTCPChannel(common, client);
}
};
final GroupChannel<ByteBuffer> channel = new GroupChannel<>(consumer, builder, copier);
channel.open(group.getSize());
return channel;
}
public static TCPGroupBuilder newTCPGroup() {
return new TCPGroupBuilder();
}
/**
* @author Ricardo Padilha
*/
public static final class TCPGroupBuilder {
private final ChannelConfig<ByteBuffer> common;
private final GroupConfig group;
TCPGroupBuilder() {
this.common = new ChannelConfig<>();
this.group = new GroupConfig();
}
/**
* @see ChannelConfig#setPool(SelectorPool)
*/
public TCPGroupBuilder setPool(final SelectorPool pool) {
common.setPool(pool);
return this;
}
/**
* @see ChannelConfig#setBufferCapacity(int)
*/
public TCPGroupBuilder setBufferCapacity(final int capacity) {
common.setBufferCapacity(capacity);
return this;
}
/**
* @see ChannelConfig#setSendBufferSize(int)
*/
public TCPGroupBuilder setSendBufferSize(final int sendBufferSize) {
common.setSendBufferSize(sendBufferSize);
return this;
}
/**
* @see ChannelConfig#setReceiveBufferSize(int)
*/
public TCPGroupBuilder setReceiveBufferSize(final int receiveBufferSize) {
common.setReceiveBufferSize(receiveBufferSize);
return this;
}
/**
* @see ChannelConfig#useDirectBuffer()
*/
public TCPGroupBuilder useDirectBuffer() {
common.useDirectBuffer();
return this;
}
/**
* @see ChannelConfig#useHeapBuffer()
*/
public TCPGroupBuilder useHeapBuffer() {
common.useHeapBuffer();
return this;
}
/**
* @see ChannelConfig#useRingBuffer()
*/
public TCPGroupBuilder useRingBuffer() {
common.useRingBuffer();
return this;
}
/**
* @see ChannelConfig#useBlockingQueue()
*/
public TCPGroupBuilder useBlockingQueue() {
common.useBlockingQueue();
return this;
}
/**
* @see ChannelConfig#useSingleInputBuffer()
*/
public TCPGroupBuilder useSingleInputBuffer() {
common.useSingleInputBuffer();
return this;
}
/**
* @see ChannelConfig#useSingleInputBuffer(net.dsys.snio.api.buffer.MessageBufferConsumer)
*/
public TCPGroupBuilder useSingleInputBuffer(final MessageBufferConsumer<ByteBuffer> consumer) {
common.useSingleInputBuffer(consumer);
return this;
}
/**
* @see ChannelConfig#useMultipleInputBuffers()
*/
public TCPGroupBuilder useMultipleInputBuffers() {
common.useMultipleInputBuffers();
return this;
}
/**
* @see GroupConfig#setMessageCodec(Factory)
*/
public TCPGroupBuilder setMessageCodec(final Factory<MessageCodec> codecs) {
group.setMessageCodec(codecs);
return this;
}
/**
* @see GroupConfig#setMessageLength(int)
*/
public TCPGroupBuilder setMessageLength(final int length) {
group.setMessageLength(length);
return this;
}
/**
* @see GroupConfig#setRateLimiter(Factory)
*/
public TCPGroupBuilder setRateLimiter(final Factory<RateLimiter> limiters) {
group.setRateLimiter(limiters);
return this;
}
/**
* @see GroupConfig#setRateLimit(long, BinaryUnit)
*/
public TCPGroupBuilder setRateLimit(final long value, final BinaryUnit unit) {
group.setRateLimit(value, unit);
return this;
}
/**
* @see GroupConfig#setGroupSize(int)
*/
public TCPGroupBuilder setGroupSize(final int size) {
group.setGroupSize(size);
return this;
}
public GroupChannel<ByteBuffer> open() throws IOException {
return openTCPGroup(common, group);
}
}
}