parent
26595471fb
commit
20aa2e1968
7
example/.gitignore
vendored
Normal file
7
example/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
#
|
||||
# native udt library extract location
|
||||
#
|
||||
|
||||
/lib
|
||||
|
@ -17,6 +17,7 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-parent</artifactId>
|
||||
@ -54,7 +55,6 @@
|
||||
<artifactId>netty-codec-socks</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java</artifactId>
|
||||
@ -64,6 +64,17 @@
|
||||
<artifactId>netty-metrics-yammer</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- see https://github.com/netty/netty/issues/874 -->
|
||||
<dependency>
|
||||
<groupId>com.yammer.metrics</groupId>
|
||||
<artifactId>metrics-core</artifactId>
|
||||
<version>2.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>netty-transport-udt</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
|
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.example.udt.echo.bytes;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.socket.nio.NioEventLoopGroup;
|
||||
import io.netty.example.udt.util.UtilConsoleReporter;
|
||||
import io.netty.example.udt.util.UtilThreadFactory;
|
||||
import io.netty.handler.logging.LogLevel;
|
||||
import io.netty.handler.logging.LoggingHandler;
|
||||
import io.netty.transport.udt.UdtChannel;
|
||||
import io.netty.transport.udt.nio.NioUdtProvider;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* UDT Byte Stream Client
|
||||
* <p>
|
||||
* Sends one message when a connection is open and echoes back any received data
|
||||
* to the server. Simply put, the echo client initiates the ping-pong traffic
|
||||
* between the echo client and server by sending the first message to the
|
||||
* server.
|
||||
*/
|
||||
public class ByteEchoClient {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(ByteEchoClient.class);
|
||||
|
||||
private final String host;
|
||||
private final int port;
|
||||
private final int messageSize;
|
||||
|
||||
public ByteEchoClient(final String host, final int port,
|
||||
final int messageSize) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.messageSize = messageSize;
|
||||
}
|
||||
|
||||
public void run() throws Exception {
|
||||
// Configure the client.
|
||||
final Bootstrap boot = new Bootstrap();
|
||||
final ThreadFactory connectFactory = new UtilThreadFactory("connect");
|
||||
final NioEventLoopGroup connectGroup = new NioEventLoopGroup(1,
|
||||
connectFactory, NioUdtProvider.BYTE_PROVIDER);
|
||||
try {
|
||||
boot.group(connectGroup)
|
||||
.channelFactory(NioUdtProvider.BYTE_CONNECTOR)
|
||||
.localAddress("localhost", 0)
|
||||
.remoteAddress(new InetSocketAddress(host, port))
|
||||
.handler(new ChannelInitializer<UdtChannel>() {
|
||||
@Override
|
||||
public void initChannel(final UdtChannel ch)
|
||||
throws Exception {
|
||||
ch.pipeline().addLast(
|
||||
new LoggingHandler(LogLevel.INFO),
|
||||
new ByteEchoClientHandler(messageSize));
|
||||
}
|
||||
});
|
||||
// Start the client.
|
||||
final ChannelFuture f = boot.connect().sync();
|
||||
// Wait until the connection is closed.
|
||||
f.channel().closeFuture().sync();
|
||||
} finally {
|
||||
// Shut down the event loop to terminate all threads.
|
||||
boot.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
log.info("init");
|
||||
|
||||
// client is reporting metrics
|
||||
UtilConsoleReporter.enable(3, TimeUnit.SECONDS);
|
||||
|
||||
final String host = "localhost";
|
||||
final int port = 1234;
|
||||
|
||||
final int messageSize = 64 * 1024;
|
||||
|
||||
new ByteEchoClient(host, port, messageSize).run();
|
||||
|
||||
log.info("done");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.example.udt.echo.bytes;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundByteHandlerAdapter;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.transport.udt.nio.NioUdtProvider;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.yammer.metrics.Metrics;
|
||||
import com.yammer.metrics.core.Meter;
|
||||
|
||||
/**
|
||||
* Handler implementation for the echo client. It initiates the ping-pong
|
||||
* traffic between the echo client and server by sending the first message to
|
||||
* the server on activation.
|
||||
*/
|
||||
public class ByteEchoClientHandler extends ChannelInboundByteHandlerAdapter {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(ByteEchoClientHandler.class.getName());
|
||||
|
||||
private final ByteBuf message;
|
||||
|
||||
final Meter meter = Metrics.newMeter(ByteEchoClientHandler.class, "rate",
|
||||
"bytes", TimeUnit.SECONDS);
|
||||
|
||||
public ByteEchoClientHandler(final int messageSize) {
|
||||
message = Unpooled.buffer(messageSize);
|
||||
|
||||
for (int i = 0; i < message.capacity(); i++) {
|
||||
message.writeByte((byte) i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(final ChannelHandlerContext ctx) throws Exception {
|
||||
log.info("ECHO active {}", NioUdtProvider.socketUDT(ctx.channel())
|
||||
.toStringOptions());
|
||||
ctx.write(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inboundBufferUpdated(final ChannelHandlerContext ctx,
|
||||
final ByteBuf in) {
|
||||
meter.mark(in.readableBytes());
|
||||
final ByteBuf out = ctx.nextOutboundByteBuffer();
|
||||
out.discardReadBytes();
|
||||
out.writeBytes(in);
|
||||
ctx.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(final ChannelHandlerContext ctx,
|
||||
final Throwable cause) {
|
||||
log.error("close the connection when an exception is raised", cause);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf newInboundBuffer(final ChannelHandlerContext ctx)
|
||||
throws Exception {
|
||||
return ctx.alloc().directBuffer(
|
||||
ctx.channel().config().getOption(ChannelOption.SO_RCVBUF));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.example.udt.echo.bytes;
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.socket.nio.NioEventLoopGroup;
|
||||
import io.netty.example.udt.util.UtilThreadFactory;
|
||||
import io.netty.handler.logging.LogLevel;
|
||||
import io.netty.handler.logging.LoggingHandler;
|
||||
import io.netty.transport.udt.UdtChannel;
|
||||
import io.netty.transport.udt.nio.NioUdtProvider;
|
||||
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* UDT Byte Stream Server
|
||||
* <p>
|
||||
* Echoes back any received data from a client.
|
||||
*/
|
||||
public class ByteEchoServer {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(ByteEchoServer.class);
|
||||
|
||||
private final int port;
|
||||
|
||||
public ByteEchoServer(final int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public void run() throws Exception {
|
||||
final ThreadFactory acceptFactory = new UtilThreadFactory("accept");
|
||||
final ThreadFactory connectFactory = new UtilThreadFactory("connect");
|
||||
final NioEventLoopGroup acceptGroup = new NioEventLoopGroup(1,
|
||||
acceptFactory, NioUdtProvider.BYTE_PROVIDER);
|
||||
final NioEventLoopGroup connectGroup = new NioEventLoopGroup(1,
|
||||
connectFactory, NioUdtProvider.BYTE_PROVIDER);
|
||||
// Configure the server.
|
||||
final ServerBootstrap boot = new ServerBootstrap();
|
||||
try {
|
||||
boot.group(acceptGroup, connectGroup)
|
||||
.channelFactory(NioUdtProvider.BYTE_ACCEPTOR)
|
||||
.option(ChannelOption.SO_BACKLOG, 10)
|
||||
.localAddress("localhost", port)
|
||||
.handler(new LoggingHandler(LogLevel.INFO))
|
||||
.childHandler(new ChannelInitializer<UdtChannel>() {
|
||||
@Override
|
||||
public void initChannel(final UdtChannel ch)
|
||||
throws Exception {
|
||||
ch.pipeline().addLast(
|
||||
new LoggingHandler(LogLevel.INFO),
|
||||
new ByteEchoServerHandler());
|
||||
}
|
||||
});
|
||||
// Start the server.
|
||||
final ChannelFuture future = boot.bind().sync();
|
||||
// Wait until the server socket is closed.
|
||||
future.channel().closeFuture().sync();
|
||||
} finally {
|
||||
// Shut down all event loops to terminate all threads.
|
||||
boot.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
log.info("init");
|
||||
|
||||
final int port = 1234;
|
||||
|
||||
new ByteEchoServer(port).run();
|
||||
|
||||
log.info("done");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.example.udt.echo.bytes;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandler.Sharable;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundByteHandlerAdapter;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.transport.udt.nio.NioUdtProvider;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Handler implementation for the echo server.
|
||||
*/
|
||||
@Sharable
|
||||
public class ByteEchoServerHandler extends ChannelInboundByteHandlerAdapter {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(ByteEchoServerHandler.class.getName());
|
||||
|
||||
@Override
|
||||
public void inboundBufferUpdated(final ChannelHandlerContext ctx,
|
||||
final ByteBuf in) {
|
||||
final ByteBuf out = ctx.nextOutboundByteBuffer();
|
||||
out.discardReadBytes();
|
||||
out.writeBytes(in);
|
||||
ctx.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(final ChannelHandlerContext ctx,
|
||||
final Throwable cause) {
|
||||
log.error("close the connection when an exception is raised", cause);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(final ChannelHandlerContext ctx) throws Exception {
|
||||
log.info("ECHO active {}", NioUdtProvider.socketUDT(ctx.channel())
|
||||
.toStringOptions());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf newInboundBuffer(final ChannelHandlerContext ctx)
|
||||
throws Exception {
|
||||
return ctx.alloc().directBuffer(
|
||||
ctx.channel().config().getOption(ChannelOption.SO_RCVBUF));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Examples show how to use UDT Byte Streams.
|
||||
*/
|
||||
package io.netty.example.udt.echo.bytes;
|
||||
|
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.example.udt.echo.message;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.socket.nio.NioEventLoopGroup;
|
||||
import io.netty.example.udt.util.UtilConsoleReporter;
|
||||
import io.netty.example.udt.util.UtilThreadFactory;
|
||||
import io.netty.handler.logging.LogLevel;
|
||||
import io.netty.handler.logging.LoggingHandler;
|
||||
import io.netty.transport.udt.UdtChannel;
|
||||
import io.netty.transport.udt.nio.NioUdtProvider;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* UDT Message Flow client
|
||||
* <p>
|
||||
* Sends one message when a connection is open and echoes back any received data
|
||||
* to the server. Simply put, the echo client initiates the ping-pong traffic
|
||||
* between the echo client and server by sending the first message to the
|
||||
* server.
|
||||
*/
|
||||
public class MsgEchoClient {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(MsgEchoClient.class);
|
||||
|
||||
private final String host;
|
||||
private final int port;
|
||||
private final int messageSize;
|
||||
|
||||
public MsgEchoClient(final String host, final int port,
|
||||
final int messageSize) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.messageSize = messageSize;
|
||||
}
|
||||
|
||||
public void run() throws Exception {
|
||||
// Configure the client.
|
||||
final Bootstrap boot = new Bootstrap();
|
||||
final ThreadFactory connectFactory = new UtilThreadFactory("connect");
|
||||
final NioEventLoopGroup connectGroup = new NioEventLoopGroup(1,
|
||||
connectFactory, NioUdtProvider.MESSAGE_PROVIDER);
|
||||
try {
|
||||
boot.group(connectGroup)
|
||||
.channelFactory(NioUdtProvider.MESSAGE_CONNECTOR)
|
||||
.localAddress("localhost", 0)
|
||||
.remoteAddress(new InetSocketAddress(host, port))
|
||||
.handler(new ChannelInitializer<UdtChannel>() {
|
||||
@Override
|
||||
public void initChannel(final UdtChannel ch)
|
||||
throws Exception {
|
||||
ch.pipeline().addLast(
|
||||
new LoggingHandler(LogLevel.INFO),
|
||||
new MsgEchoClientHandler(messageSize));
|
||||
}
|
||||
});
|
||||
// Start the client.
|
||||
final ChannelFuture f = boot.connect().sync();
|
||||
// Wait until the connection is closed.
|
||||
f.channel().closeFuture().sync();
|
||||
} finally {
|
||||
// Shut down the event loop to terminate all threads.
|
||||
boot.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
log.info("init");
|
||||
|
||||
// client is reporting metrics
|
||||
UtilConsoleReporter.enable(3, TimeUnit.SECONDS);
|
||||
|
||||
final String host = "localhost";
|
||||
|
||||
final int port = 1234;
|
||||
final int messageSize = 64 * 1024;
|
||||
|
||||
new MsgEchoClient(host, port, messageSize).run();
|
||||
|
||||
log.info("done");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.example.udt.echo.message;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.MessageBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundMessageHandlerAdapter;
|
||||
import io.netty.transport.udt.UdtMessage;
|
||||
import io.netty.transport.udt.nio.NioUdtProvider;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.yammer.metrics.Metrics;
|
||||
import com.yammer.metrics.core.Meter;
|
||||
|
||||
/**
|
||||
* Handler implementation for the echo client. It initiates the ping-pong
|
||||
* traffic between the echo client and server by sending the first message to
|
||||
* the server on activation.
|
||||
*/
|
||||
public class MsgEchoClientHandler extends
|
||||
ChannelInboundMessageHandlerAdapter<UdtMessage> {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(MsgEchoClientHandler.class.getName());
|
||||
|
||||
private final UdtMessage message;
|
||||
|
||||
public MsgEchoClientHandler(final int messageSize) {
|
||||
final ByteBuf byteBuf = Unpooled.buffer(messageSize);
|
||||
for (int i = 0; i < byteBuf.capacity(); i++) {
|
||||
byteBuf.writeByte((byte) i);
|
||||
}
|
||||
message = new UdtMessage(byteBuf);
|
||||
}
|
||||
|
||||
final Meter meter = Metrics.newMeter(MsgEchoClientHandler.class, "rate",
|
||||
"bytes", TimeUnit.SECONDS);
|
||||
|
||||
@Override
|
||||
public void channelActive(final ChannelHandlerContext ctx) throws Exception {
|
||||
log.info("ECHO active {}", NioUdtProvider.socketUDT(ctx.channel())
|
||||
.toStringOptions());
|
||||
final MessageBuf<Object> out = ctx.nextOutboundMessageBuffer();
|
||||
out.add(message);
|
||||
ctx.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(final ChannelHandlerContext ctx,
|
||||
final Throwable cause) {
|
||||
log.error("close the connection when an exception is raised", cause);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void messageReceived(final ChannelHandlerContext ctx,
|
||||
final UdtMessage message) throws Exception {
|
||||
final ByteBuf byteBuf = message.data();
|
||||
meter.mark(byteBuf.readableBytes());
|
||||
final MessageBuf<Object> out = ctx.nextOutboundMessageBuffer();
|
||||
out.add(message);
|
||||
ctx.flush();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.example.udt.echo.message;
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.socket.nio.NioEventLoopGroup;
|
||||
import io.netty.example.udt.util.UtilThreadFactory;
|
||||
import io.netty.handler.logging.LogLevel;
|
||||
import io.netty.handler.logging.LoggingHandler;
|
||||
import io.netty.transport.udt.UdtChannel;
|
||||
import io.netty.transport.udt.nio.NioUdtProvider;
|
||||
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* UDT Message Flow Server
|
||||
* <p>
|
||||
* Echoes back any received data from a client.
|
||||
*/
|
||||
public class MsgEchoServer {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(MsgEchoServer.class);
|
||||
|
||||
private final int port;
|
||||
|
||||
public MsgEchoServer(final int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public void run() throws Exception {
|
||||
final ThreadFactory acceptFactory = new UtilThreadFactory("accept");
|
||||
final ThreadFactory connectFactory = new UtilThreadFactory("connect");
|
||||
final NioEventLoopGroup acceptGroup = new NioEventLoopGroup(1,
|
||||
acceptFactory, NioUdtProvider.MESSAGE_PROVIDER);
|
||||
final NioEventLoopGroup connectGroup = new NioEventLoopGroup(1,
|
||||
connectFactory, NioUdtProvider.MESSAGE_PROVIDER);
|
||||
// Configure the server.
|
||||
final ServerBootstrap boot = new ServerBootstrap();
|
||||
try {
|
||||
boot.group(acceptGroup, connectGroup)
|
||||
.channelFactory(NioUdtProvider.MESSAGE_ACCEPTOR)
|
||||
.option(ChannelOption.SO_BACKLOG, 10)
|
||||
.localAddress("localhost", port)
|
||||
.handler(new LoggingHandler(LogLevel.INFO))
|
||||
.childHandler(new ChannelInitializer<UdtChannel>() {
|
||||
@Override
|
||||
public void initChannel(final UdtChannel ch)
|
||||
throws Exception {
|
||||
ch.pipeline().addLast(
|
||||
new LoggingHandler(LogLevel.INFO),
|
||||
new MsgEchoServerHandler());
|
||||
}
|
||||
});
|
||||
// Start the server.
|
||||
final ChannelFuture future = boot.bind().sync();
|
||||
// Wait until the server socket is closed.
|
||||
future.channel().closeFuture().sync();
|
||||
} finally {
|
||||
// Shut down all event loops to terminate all threads.
|
||||
boot.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
log.info("init");
|
||||
|
||||
final int port = 1234;
|
||||
|
||||
new MsgEchoServer(port).run();
|
||||
|
||||
log.info("done");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.example.udt.echo.message;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.MessageBuf;
|
||||
import io.netty.channel.ChannelHandler.Sharable;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundMessageHandlerAdapter;
|
||||
import io.netty.transport.udt.UdtMessage;
|
||||
import io.netty.transport.udt.nio.NioUdtProvider;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Handler implementation for the echo server.
|
||||
*/
|
||||
@Sharable
|
||||
public class MsgEchoServerHandler extends
|
||||
ChannelInboundMessageHandlerAdapter<UdtMessage> {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(MsgEchoServerHandler.class.getName());
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(final ChannelHandlerContext ctx,
|
||||
final Throwable cause) {
|
||||
log.error("close the connection when an exception is raised", cause);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(final ChannelHandlerContext ctx) throws Exception {
|
||||
log.info("ECHO active {}", NioUdtProvider.socketUDT(ctx.channel())
|
||||
.toStringOptions());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void messageReceived(final ChannelHandlerContext ctx,
|
||||
final UdtMessage message) throws Exception {
|
||||
final ByteBuf byteBuf = message.data();
|
||||
final MessageBuf<Object> out = ctx.nextOutboundMessageBuffer();
|
||||
out.add(message);
|
||||
ctx.flush();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Examples show how to use UDT Message Flows.
|
||||
*/
|
||||
package io.netty.example.udt.echo.message;
|
||||
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Examples show how to use UDT with simple Echo Handlers.
|
||||
*/
|
||||
package io.netty.example.udt.echo;
|
||||
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.example.udt.echo.rendevous;
|
||||
|
||||
/**
|
||||
* Peer to Peer Config
|
||||
*/
|
||||
public final class Config {
|
||||
|
||||
private Config() {
|
||||
}
|
||||
|
||||
public static final String hostOne = "localhost";
|
||||
public static final int portOne = 1231;
|
||||
|
||||
public static final String hostTwo = "localhost";
|
||||
public static final int portTwo = 1232;
|
||||
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.example.udt.echo.rendevous;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.socket.nio.NioEventLoopGroup;
|
||||
import io.netty.example.udt.util.UtilThreadFactory;
|
||||
import io.netty.handler.logging.LogLevel;
|
||||
import io.netty.handler.logging.LoggingHandler;
|
||||
import io.netty.transport.udt.UdtChannel;
|
||||
import io.netty.transport.udt.nio.NioUdtProvider;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* UDT Message Flow Peer
|
||||
* <p>
|
||||
* Sends one message when a connection is open and echoes back any received data
|
||||
* to the other peer.
|
||||
*/
|
||||
public abstract class MsgEchoPeerBase {
|
||||
|
||||
protected static final Logger log = LoggerFactory
|
||||
.getLogger(MsgEchoPeerBase.class);
|
||||
|
||||
protected final int messageSize;
|
||||
protected final InetSocketAddress self;
|
||||
protected final InetSocketAddress peer;
|
||||
|
||||
public MsgEchoPeerBase(final InetSocketAddress self,
|
||||
final InetSocketAddress peer, final int messageSize) {
|
||||
this.messageSize = messageSize;
|
||||
this.self = self;
|
||||
this.peer = peer;
|
||||
}
|
||||
|
||||
public void run() throws Exception {
|
||||
// Configure the peer.
|
||||
final Bootstrap boot = new Bootstrap();
|
||||
final ThreadFactory connectFactory = new UtilThreadFactory("rendezvous");
|
||||
final NioEventLoopGroup connectGroup = new NioEventLoopGroup(1,
|
||||
connectFactory, NioUdtProvider.MESSAGE_PROVIDER);
|
||||
try {
|
||||
boot.group(connectGroup)
|
||||
.channelFactory(NioUdtProvider.MESSAGE_RENDEZVOUS)
|
||||
.localAddress(self).remoteAddress(peer)
|
||||
.handler(new ChannelInitializer<UdtChannel>() {
|
||||
@Override
|
||||
public void initChannel(final UdtChannel ch)
|
||||
throws Exception {
|
||||
ch.pipeline().addLast(
|
||||
new LoggingHandler(LogLevel.INFO),
|
||||
new MsgEchoPeerHandler(messageSize));
|
||||
}
|
||||
});
|
||||
// Start the peer.
|
||||
final ChannelFuture f = boot.connect().sync();
|
||||
// Wait until the connection is closed.
|
||||
f.channel().closeFuture().sync();
|
||||
} finally {
|
||||
// Shut down the event loop to terminate all threads.
|
||||
boot.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.example.udt.echo.rendevous;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.MessageBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundMessageHandlerAdapter;
|
||||
import io.netty.transport.udt.UdtMessage;
|
||||
import io.netty.transport.udt.nio.NioUdtProvider;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.yammer.metrics.Metrics;
|
||||
import com.yammer.metrics.core.Meter;
|
||||
|
||||
/**
|
||||
* Handler implementation for the echo peer. It initiates the ping-pong traffic
|
||||
* between the echo peers by sending the first message to the other peer on
|
||||
* activation.
|
||||
*/
|
||||
public class MsgEchoPeerHandler extends
|
||||
ChannelInboundMessageHandlerAdapter<UdtMessage> {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(MsgEchoPeerHandler.class.getName());
|
||||
|
||||
private final UdtMessage message;
|
||||
|
||||
public MsgEchoPeerHandler(final int messageSize) {
|
||||
final ByteBuf byteBuf = Unpooled.buffer(messageSize);
|
||||
for (int i = 0; i < byteBuf.capacity(); i++) {
|
||||
byteBuf.writeByte((byte) i);
|
||||
}
|
||||
message = new UdtMessage(byteBuf);
|
||||
}
|
||||
|
||||
final Meter meter = Metrics.newMeter(MsgEchoPeerHandler.class, "rate",
|
||||
"bytes", TimeUnit.SECONDS);
|
||||
|
||||
@Override
|
||||
public void channelActive(final ChannelHandlerContext ctx) throws Exception {
|
||||
log.info("ECHO active {}", NioUdtProvider.socketUDT(ctx.channel())
|
||||
.toStringOptions());
|
||||
final MessageBuf<Object> out = ctx.nextOutboundMessageBuffer();
|
||||
out.add(message);
|
||||
ctx.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(final ChannelHandlerContext ctx,
|
||||
final Throwable cause) {
|
||||
log.error("close the connection when an exception is raised", cause);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void messageReceived(final ChannelHandlerContext ctx,
|
||||
final UdtMessage message) throws Exception {
|
||||
final ByteBuf byteBuf = message.data();
|
||||
meter.mark(byteBuf.readableBytes());
|
||||
final MessageBuf<Object> out = ctx.nextOutboundMessageBuffer();
|
||||
out.add(message);
|
||||
ctx.flush();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.example.udt.echo.rendevous;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
/**
|
||||
* UDT Message Flow Peer
|
||||
* <p>
|
||||
* Sends one message when a connection is open and echoes back any received data
|
||||
* to the other peer.
|
||||
*/
|
||||
public class MsgEchoPeerOne extends MsgEchoPeerBase {
|
||||
|
||||
public MsgEchoPeerOne(final InetSocketAddress self,
|
||||
final InetSocketAddress peer, final int messageSize) {
|
||||
super(self, peer, messageSize);
|
||||
}
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
log.info("init");
|
||||
|
||||
// peer one is not reporting metrics
|
||||
// ConsoleReporterUDT.enable(3, TimeUnit.SECONDS);
|
||||
|
||||
final int messageSize = 64 * 1024;
|
||||
|
||||
final InetSocketAddress self = new InetSocketAddress(Config.hostOne,
|
||||
Config.portOne);
|
||||
|
||||
final InetSocketAddress peer = new InetSocketAddress(Config.hostTwo,
|
||||
Config.portTwo);
|
||||
|
||||
new MsgEchoPeerOne(self, peer, messageSize).run();
|
||||
|
||||
log.info("done");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.example.udt.echo.rendevous;
|
||||
|
||||
import io.netty.example.udt.util.UtilConsoleReporter;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* UDT Message Flow Peer
|
||||
* <p>
|
||||
* Sends one message when a connection is open and echoes back any received data
|
||||
* to the other peer.
|
||||
*/
|
||||
public class MsgEchoPeerTwo extends MsgEchoPeerBase {
|
||||
|
||||
public MsgEchoPeerTwo(final InetSocketAddress self,
|
||||
final InetSocketAddress peer, final int messageSize) {
|
||||
super(self, peer, messageSize);
|
||||
}
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
log.info("init");
|
||||
|
||||
// peer two is reporting metrics
|
||||
UtilConsoleReporter.enable(3, TimeUnit.SECONDS);
|
||||
|
||||
final int messageSize = 64 * 1024;
|
||||
|
||||
final InetSocketAddress self = new InetSocketAddress(Config.hostTwo,
|
||||
Config.portTwo);
|
||||
|
||||
final InetSocketAddress peer = new InetSocketAddress(Config.hostOne,
|
||||
Config.portOne);
|
||||
|
||||
new MsgEchoPeerTwo(self, peer, messageSize).run();
|
||||
|
||||
log.info("done");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Examples show how to use UDT Message Rendezvous.
|
||||
*/
|
||||
package io.netty.example.udt.echo.rendevous;
|
||||
|
21
example/src/main/java/io/netty/example/udt/package-info.java
Normal file
21
example/src/main/java/io/netty/example/udt/package-info.java
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Examples show how to use UDT.
|
||||
*/
|
||||
package io.netty.example.udt;
|
||||
|
@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.example.udt.util;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.yammer.metrics.Metrics;
|
||||
import com.yammer.metrics.core.Clock;
|
||||
import com.yammer.metrics.core.Counter;
|
||||
import com.yammer.metrics.core.Gauge;
|
||||
import com.yammer.metrics.core.Histogram;
|
||||
import com.yammer.metrics.core.Metered;
|
||||
import com.yammer.metrics.core.Metric;
|
||||
import com.yammer.metrics.core.MetricName;
|
||||
import com.yammer.metrics.core.MetricPredicate;
|
||||
import com.yammer.metrics.core.MetricProcessor;
|
||||
import com.yammer.metrics.core.MetricsRegistry;
|
||||
import com.yammer.metrics.core.Timer;
|
||||
import com.yammer.metrics.reporting.AbstractPollingReporter;
|
||||
import com.yammer.metrics.stats.Snapshot;
|
||||
|
||||
/**
|
||||
* A simple reporters which prints out application metrics to a
|
||||
* {@link PrintStream} periodically.
|
||||
*/
|
||||
public class UtilConsoleReporter extends AbstractPollingReporter implements
|
||||
MetricProcessor<PrintStream> {
|
||||
private static final int CONSOLE_WIDTH = 80;
|
||||
|
||||
/**
|
||||
* Enables the console reporter for the default metrics registry, and causes
|
||||
* it to print to STDOUT with the specified period.
|
||||
*/
|
||||
public static void enable(final long period, final TimeUnit unit) {
|
||||
enable(Metrics.defaultRegistry(), period, unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the console reporter for the given metrics registry, and causes
|
||||
* it to print to STDOUT with the specified period and unrestricted output.
|
||||
*/
|
||||
public static void enable(final MetricsRegistry metricsRegistry,
|
||||
final long period, final TimeUnit unit) {
|
||||
final UtilConsoleReporter reporter = new UtilConsoleReporter(
|
||||
metricsRegistry, System.out, MetricPredicate.ALL);
|
||||
reporter.start(period, unit);
|
||||
}
|
||||
|
||||
private final PrintStream out;
|
||||
private final MetricPredicate predicate;
|
||||
private final Clock clock;
|
||||
private final TimeZone timeZone;
|
||||
private final Locale locale;
|
||||
|
||||
/**
|
||||
* Creates a new {@link UtilConsoleReporter} for the default metrics
|
||||
* registry, with unrestricted output.
|
||||
*/
|
||||
public UtilConsoleReporter(final PrintStream out) {
|
||||
this(Metrics.defaultRegistry(), out, MetricPredicate.ALL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link UtilConsoleReporter} for a given metrics registry.
|
||||
*/
|
||||
public UtilConsoleReporter(final MetricsRegistry metricsRegistry,
|
||||
final PrintStream out, final MetricPredicate predicate) {
|
||||
this(metricsRegistry, out, predicate, Clock.defaultClock(), TimeZone
|
||||
.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link UtilConsoleReporter} for a given metrics registry.
|
||||
*/
|
||||
public UtilConsoleReporter(final MetricsRegistry metricsRegistry,
|
||||
final PrintStream out, final MetricPredicate predicate,
|
||||
final Clock clock, final TimeZone timeZone) {
|
||||
this(metricsRegistry, out, predicate, clock, timeZone, Locale
|
||||
.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link UtilConsoleReporter} for a given metrics registry.
|
||||
*/
|
||||
public UtilConsoleReporter(final MetricsRegistry metricsRegistry,
|
||||
final PrintStream out, final MetricPredicate predicate,
|
||||
final Clock clock, final TimeZone timeZone, final Locale locale) {
|
||||
super(metricsRegistry, "console-reporter");
|
||||
this.out = out;
|
||||
this.predicate = predicate;
|
||||
this.clock = clock;
|
||||
this.timeZone = timeZone;
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final DateFormat format = DateFormat.getDateTimeInstance(
|
||||
DateFormat.SHORT, DateFormat.MEDIUM, locale);
|
||||
format.setTimeZone(timeZone);
|
||||
final String dateTime = format.format(new Date(clock.time()));
|
||||
out.print(dateTime);
|
||||
out.print(' ');
|
||||
for (int i = 0; i < (CONSOLE_WIDTH - dateTime.length() - 1); i++) {
|
||||
out.print('=');
|
||||
}
|
||||
out.println();
|
||||
for (final Entry<String, SortedMap<MetricName, Metric>> entry : getMetricsRegistry()
|
||||
.groupedMetrics(predicate).entrySet()) {
|
||||
out.print(entry.getKey());
|
||||
out.println(':');
|
||||
for (final Entry<MetricName, Metric> subEntry : entry
|
||||
.getValue().entrySet()) {
|
||||
out.print(" ");
|
||||
out.print(subEntry.getKey().getName());
|
||||
out.println(':');
|
||||
subEntry.getValue().processWith(this, subEntry.getKey(),
|
||||
out);
|
||||
out.println();
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
out.println();
|
||||
out.flush();
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace(out);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processGauge(final MetricName name, final Gauge<?> gauge,
|
||||
final PrintStream stream) {
|
||||
stream.printf(locale, " value = %s\n", gauge.value());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCounter(final MetricName name, final Counter counter,
|
||||
final PrintStream stream) {
|
||||
stream.printf(locale, " count = %,d\n", counter.count());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processMeter(final MetricName name, final Metered meter,
|
||||
final PrintStream stream) {
|
||||
final String unit = abbrev(meter.rateUnit());
|
||||
stream.printf(locale, " count = %,d\n", meter.count());
|
||||
stream.printf(locale, " mean rate = %,2.2f %s/%s\n",
|
||||
meter.meanRate(), meter.eventType(), unit);
|
||||
stream.printf(locale, " 1-minute rate = %,2.2f %s/%s\n",
|
||||
meter.oneMinuteRate(), meter.eventType(), unit);
|
||||
stream.printf(locale, " 5-minute rate = %,2.2f %s/%s\n",
|
||||
meter.fiveMinuteRate(), meter.eventType(), unit);
|
||||
stream.printf(locale, " 15-minute rate = %,2.2f %s/%s\n",
|
||||
meter.fifteenMinuteRate(), meter.eventType(), unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processHistogram(final MetricName name,
|
||||
final Histogram histogram, final PrintStream stream) {
|
||||
final Snapshot snapshot = histogram.getSnapshot();
|
||||
stream.printf(locale, " min = %,2.2f\n", histogram.min());
|
||||
stream.printf(locale, " max = %,2.2f\n", histogram.max());
|
||||
stream.printf(locale, " mean = %,2.2f\n", histogram.mean());
|
||||
stream.printf(locale, " stddev = %,2.2f\n",
|
||||
histogram.stdDev());
|
||||
stream.printf(locale, " median = %,2.2f\n",
|
||||
snapshot.getMedian());
|
||||
stream.printf(locale, " 75%% <= %,2.2f\n",
|
||||
snapshot.get75thPercentile());
|
||||
stream.printf(locale, " 95%% <= %,2.2f\n",
|
||||
snapshot.get95thPercentile());
|
||||
stream.printf(locale, " 98%% <= %,2.2f\n",
|
||||
snapshot.get98thPercentile());
|
||||
stream.printf(locale, " 99%% <= %,2.2f\n",
|
||||
snapshot.get99thPercentile());
|
||||
stream.printf(locale, " 99.9%% <= %,2.2f\n",
|
||||
snapshot.get999thPercentile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processTimer(final MetricName name, final Timer timer,
|
||||
final PrintStream stream) {
|
||||
processMeter(name, timer, stream);
|
||||
final String durationUnit = abbrev(timer.durationUnit());
|
||||
final Snapshot snapshot = timer.getSnapshot();
|
||||
stream.printf(locale, " min = %,2.2f %s\n", timer.min(),
|
||||
durationUnit);
|
||||
stream.printf(locale, " max = %,2.2f %s\n", timer.max(),
|
||||
durationUnit);
|
||||
stream.printf(locale, " mean = %,2.2f %s\n", timer.mean(),
|
||||
durationUnit);
|
||||
stream.printf(locale, " stddev = %,2.2f %s\n",
|
||||
timer.stdDev(), durationUnit);
|
||||
stream.printf(locale, " median = %,2.2f %s\n",
|
||||
snapshot.getMedian(), durationUnit);
|
||||
stream.printf(locale, " 75%% <= %,2.2f %s\n",
|
||||
snapshot.get75thPercentile(), durationUnit);
|
||||
stream.printf(locale, " 95%% <= %,2.2f %s\n",
|
||||
snapshot.get95thPercentile(), durationUnit);
|
||||
stream.printf(locale, " 98%% <= %,2.2f %s\n",
|
||||
snapshot.get98thPercentile(), durationUnit);
|
||||
stream.printf(locale, " 99%% <= %,2.2f %s\n",
|
||||
snapshot.get99thPercentile(), durationUnit);
|
||||
stream.printf(locale, " 99.9%% <= %,2.2f %s\n",
|
||||
snapshot.get999thPercentile(), durationUnit);
|
||||
}
|
||||
|
||||
private String abbrev(final TimeUnit unit) {
|
||||
switch (unit) {
|
||||
case NANOSECONDS:
|
||||
return "ns";
|
||||
case MICROSECONDS:
|
||||
return "us";
|
||||
case MILLISECONDS:
|
||||
return "ms";
|
||||
case SECONDS:
|
||||
return "s";
|
||||
case MINUTES:
|
||||
return "m";
|
||||
case HOURS:
|
||||
return "h";
|
||||
case DAYS:
|
||||
return "d";
|
||||
default:
|
||||
throw new IllegalArgumentException("Unrecognized TimeUnit: " + unit);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.example.udt.util;
|
||||
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Custom thread factory to use with examples.
|
||||
*/
|
||||
public class UtilThreadFactory implements ThreadFactory {
|
||||
|
||||
private static final AtomicInteger counter = new AtomicInteger();
|
||||
|
||||
private final String name;
|
||||
|
||||
public UtilThreadFactory(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Thread newThread(final Runnable runnable) {
|
||||
return new Thread(runnable, name + "-" + counter.getAndIncrement());
|
||||
};
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Utilities for UDT examples.
|
||||
*/
|
||||
package io.netty.example.udt.util;
|
||||
|
7
pom.xml
7
pom.xml
@ -80,6 +80,7 @@
|
||||
<module>codec-socks</module>
|
||||
<module>transport</module>
|
||||
<module>transport-sctp</module>
|
||||
<module>transport-udt</module>
|
||||
<module>handler</module>
|
||||
<module>metrics-yammer</module>
|
||||
<module>example</module>
|
||||
@ -220,9 +221,9 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.6.6</version>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.0.9</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
7
transport-udt/.gitignore
vendored
Normal file
7
transport-udt/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
#
|
||||
# native udt library extract location
|
||||
#
|
||||
|
||||
/lib
|
||||
|
101
transport-udt/pom.xml
Normal file
101
transport-udt/pom.xml
Normal file
@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2012 The Netty Project
|
||||
~
|
||||
~ The Netty Project licenses this file to you 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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-parent</artifactId>
|
||||
<version>4.0.0.Beta1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>netty-transport-udt</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Netty/Transport/UDT</name>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- MAIN -->
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>netty-buffer</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>netty-transport</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.barchart.udt</groupId>
|
||||
<artifactId>barchart-udt-bundle</artifactId>
|
||||
<version>2.2.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- TEST -->
|
||||
|
||||
<!-- see https://github.com/netty/netty/issues/874 -->
|
||||
<dependency>
|
||||
<groupId>com.yammer.metrics</groupId>
|
||||
<artifactId>metrics-core</artifactId>
|
||||
<version>2.2.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.0.9</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.caliper</groupId>
|
||||
<artifactId>caliper</artifactId>
|
||||
<version>0.5-rc1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<forkMode>always</forkMode>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt;
|
||||
|
||||
import static io.netty.channel.ChannelOption.*;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.DefaultChannelConfig;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import com.barchart.udt.OptionUDT;
|
||||
import com.barchart.udt.SocketUDT;
|
||||
import com.barchart.udt.nio.ChannelUDT;
|
||||
|
||||
/**
|
||||
* The default {@link UdtChannelConfig} implementation.
|
||||
*/
|
||||
public class DefaultUdtChannelConfig extends DefaultChannelConfig implements
|
||||
UdtChannelConfig {
|
||||
|
||||
private static final int K = 1024;
|
||||
private static final int M = K * K;
|
||||
|
||||
private volatile int protocolReceiveBuferSize = 10 * M;
|
||||
private volatile int protocolSendBuferSize = 10 * M;
|
||||
|
||||
private volatile int systemReceiveBufferSize = 1 * M;
|
||||
private volatile int systemSendBuferSize = 1 * M;
|
||||
|
||||
private volatile int allocatorReceiveBufferSize = 128 * K;
|
||||
private volatile int allocatorSendBufferSize = 128 * K;
|
||||
|
||||
private volatile int backlog = 64;
|
||||
private volatile int soLinger;
|
||||
|
||||
private volatile boolean reuseAddress = true;
|
||||
|
||||
public DefaultUdtChannelConfig(final UdtChannel channel,
|
||||
final ChannelUDT channelUDT, final boolean apply)
|
||||
throws IOException {
|
||||
super(channel);
|
||||
if (apply) {
|
||||
apply(channelUDT);
|
||||
}
|
||||
}
|
||||
|
||||
protected void apply(final ChannelUDT channelUDT) throws IOException {
|
||||
final SocketUDT socketUDT = channelUDT.socketUDT();
|
||||
socketUDT.setReuseAddress(isReuseAddress());
|
||||
socketUDT.setSendBufferSize(getSendBufferSize());
|
||||
if (getSoLinger() <= 0) {
|
||||
socketUDT.setSoLinger(false, 0);
|
||||
} else {
|
||||
socketUDT.setSoLinger(true, getSoLinger());
|
||||
}
|
||||
socketUDT.setOption(OptionUDT.Protocol_Receive_Buffer_Size,
|
||||
getProtocolReceiveBufferSize());
|
||||
socketUDT.setOption(OptionUDT.Protocol_Send_Buffer_Size,
|
||||
getProtocolSendBufferSize());
|
||||
socketUDT.setOption(OptionUDT.System_Receive_Buffer_Size,
|
||||
getSystemReceiveBufferSize());
|
||||
socketUDT.setOption(OptionUDT.System_Send_Buffer_Size,
|
||||
getSystemSendBufferSize());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtocolReceiveBufferSize() {
|
||||
return protocolReceiveBuferSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBacklog() {
|
||||
return backlog;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T getOption(final ChannelOption<T> option) {
|
||||
if (option == PROTOCOL_RECEIVE_BUFFER_SIZE) {
|
||||
return (T) Integer.valueOf(getProtocolReceiveBufferSize());
|
||||
}
|
||||
if (option == PROTOCOL_SEND_BUFFER_SIZE) {
|
||||
return (T) Integer.valueOf(getProtocolSendBufferSize());
|
||||
}
|
||||
if (option == SYSTEM_RECEIVE_BUFFER_SIZE) {
|
||||
return (T) Integer.valueOf(getSystemReceiveBufferSize());
|
||||
}
|
||||
if (option == SYSTEM_SEND_BUFFER_SIZE) {
|
||||
return (T) Integer.valueOf(getSystemSendBufferSize());
|
||||
}
|
||||
if (option == SO_RCVBUF) {
|
||||
return (T) Integer.valueOf(getReceiveBufferSize());
|
||||
}
|
||||
if (option == SO_SNDBUF) {
|
||||
return (T) Integer.valueOf(getSendBufferSize());
|
||||
}
|
||||
if (option == SO_REUSEADDR) {
|
||||
return (T) Boolean.valueOf(isReuseAddress());
|
||||
}
|
||||
if (option == SO_LINGER) {
|
||||
return (T) Integer.valueOf(getSoLinger());
|
||||
}
|
||||
if (option == SO_BACKLOG) {
|
||||
return (T) Integer.valueOf(getBacklog());
|
||||
}
|
||||
return super.getOption(option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ChannelOption<?>, Object> getOptions() {
|
||||
return getOptions(super.getOptions(), PROTOCOL_RECEIVE_BUFFER_SIZE,
|
||||
PROTOCOL_SEND_BUFFER_SIZE, SYSTEM_RECEIVE_BUFFER_SIZE,
|
||||
SYSTEM_SEND_BUFFER_SIZE, SO_RCVBUF, SO_SNDBUF, SO_REUSEADDR,
|
||||
SO_LINGER, SO_BACKLOG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getReceiveBufferSize() {
|
||||
return allocatorReceiveBufferSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSendBufferSize() {
|
||||
return allocatorSendBufferSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoLinger() {
|
||||
return soLinger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReuseAddress() {
|
||||
return reuseAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UdtChannelConfig setProtocolReceiveBufferSize(final int allocator) {
|
||||
this.protocolReceiveBuferSize = allocator;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UdtChannelConfig setBacklog(final int backlog) {
|
||||
this.backlog = backlog;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean setOption(final ChannelOption<T> option, final T value) {
|
||||
validate(option, value);
|
||||
if (option == PROTOCOL_RECEIVE_BUFFER_SIZE) {
|
||||
setProtocolReceiveBufferSize((Integer) value);
|
||||
} else if (option == PROTOCOL_SEND_BUFFER_SIZE) {
|
||||
setProtocolSendBufferSize((Integer) value);
|
||||
} else if (option == SYSTEM_RECEIVE_BUFFER_SIZE) {
|
||||
setSystemReceiveBufferSize((Integer) value);
|
||||
} else if (option == SYSTEM_SEND_BUFFER_SIZE) {
|
||||
setSystemSendBufferSize((Integer) value);
|
||||
} else if (option == SO_RCVBUF) {
|
||||
setReceiveBufferSize((Integer) value);
|
||||
} else if (option == SO_SNDBUF) {
|
||||
setSendBufferSize((Integer) value);
|
||||
} else if (option == SO_REUSEADDR) {
|
||||
setReuseAddress((Boolean) value);
|
||||
} else if (option == SO_LINGER) {
|
||||
setSoLinger((Integer) value);
|
||||
} else if (option == SO_BACKLOG) {
|
||||
setBacklog((Integer) value);
|
||||
} else {
|
||||
return super.setOption(option, value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UdtChannelConfig setReceiveBufferSize(final int receiveBufferSize) {
|
||||
allocatorReceiveBufferSize = receiveBufferSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UdtChannelConfig setReuseAddress(final boolean reuseAddress) {
|
||||
this.reuseAddress = reuseAddress;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UdtChannelConfig setSendBufferSize(final int sendBufferSize) {
|
||||
allocatorSendBufferSize = sendBufferSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UdtChannelConfig setSoLinger(final int soLinger) {
|
||||
this.soLinger = soLinger;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSystemReceiveBufferSize() {
|
||||
return systemReceiveBufferSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UdtChannelConfig setSystemSendBufferSize(
|
||||
final int systemReceiveBufferSize) {
|
||||
this.systemReceiveBufferSize = systemReceiveBufferSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtocolSendBufferSize() {
|
||||
return protocolSendBuferSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UdtChannelConfig setProtocolSendBufferSize(
|
||||
final int protocolSendBuferSize) {
|
||||
this.protocolSendBuferSize = protocolSendBuferSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UdtChannelConfig setSystemReceiveBufferSize(
|
||||
final int systemSendBuferSize) {
|
||||
this.systemSendBuferSize = systemSendBuferSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSystemSendBufferSize() {
|
||||
return systemSendBuferSize;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.transport.udt.nio.NioUdtProvider;
|
||||
|
||||
/**
|
||||
* UDT {@link Channel}.
|
||||
* <p>
|
||||
* Supported UDT {@link UdtChannel} are available via {@link NioUdtProvider}.
|
||||
*/
|
||||
public interface UdtChannel extends Channel {
|
||||
|
||||
/**
|
||||
* Returns the {@link UdtChannelConfig} of the channel.
|
||||
*/
|
||||
@Override
|
||||
UdtChannelConfig config();
|
||||
|
||||
}
|
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt;
|
||||
|
||||
import io.netty.channel.ChannelConfig;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelOption;
|
||||
|
||||
import com.barchart.udt.OptionUDT;
|
||||
import com.barchart.udt.TypeUDT;
|
||||
import com.barchart.udt.nio.KindUDT;
|
||||
|
||||
/**
|
||||
* A {@link ChannelConfig} for a {@link UdtChannel}.
|
||||
* <p>
|
||||
* <h3>Available options</h3>
|
||||
* In addition to the options provided by {@link ChannelConfig},
|
||||
* {@link UdtChannelConfig} allows the following options in the option map:
|
||||
* <p>
|
||||
* <table border="1" cellspacing="0" cellpadding="6">
|
||||
* <tr>
|
||||
* <th>Name</th>
|
||||
* <th>Associated setter method</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@code "reuseAddress"}</td>
|
||||
* <td>{@link #setReuseAddress(boolean)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@code "soLinger"}</td>
|
||||
* <td>{@link #setSoLinger(int)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@code "receiveBufferSize"}</td>
|
||||
* <td>{@link #setReceiveBufferSize(int)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@code "sendBufferSize"}</td>
|
||||
* <td>{@link #setSendBufferSize(int)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@code "protocolReceiveBuferSize"}</td>
|
||||
* <td>{@link #setProtocolBufferSize(int)}</td>
|
||||
* <tr>
|
||||
* <tr>
|
||||
* <td>{@code "systemReceiveBufferSize"}</td>
|
||||
* <td>{@link #setSystemBufferSize(int)}</td>
|
||||
* <tr>
|
||||
* </table>
|
||||
* <p>
|
||||
* Note that {@link TypeUDT#DATAGRAM} message oriented channels treat
|
||||
* {@code "receiveBufferSize"} and {@code "sendBufferSize"} as maximum message
|
||||
* size. If received or sent message does not fit specified sizes,
|
||||
* {@link ChannelException} will be thrown.
|
||||
*/
|
||||
public interface UdtChannelConfig extends ChannelConfig {
|
||||
|
||||
/**
|
||||
* See {@link OptionUDT#Protocol_Receive_Buffer_Size}.
|
||||
*/
|
||||
ChannelOption<Integer> PROTOCOL_RECEIVE_BUFFER_SIZE = new ChannelOption<Integer>(
|
||||
"PROTOCOL_RECEIVE_BUFFER_SIZE");
|
||||
|
||||
/**
|
||||
* See {@link OptionUDT#Protocol_Send_Buffer_Size}.
|
||||
*/
|
||||
ChannelOption<Integer> PROTOCOL_SEND_BUFFER_SIZE = new ChannelOption<Integer>(
|
||||
"PROTOCOL_SEND_BUFFER_SIZE");
|
||||
|
||||
/**
|
||||
* See {@link OptionUDT#System_Receive_Buffer_Size}.
|
||||
*/
|
||||
ChannelOption<Integer> SYSTEM_RECEIVE_BUFFER_SIZE = new ChannelOption<Integer>(
|
||||
"SYSTEM_RECEIVE_BUFFER_SIZE");
|
||||
|
||||
/**
|
||||
* See {@link OptionUDT#System_Send_Buffer_Size}.
|
||||
*/
|
||||
ChannelOption<Integer> SYSTEM_SEND_BUFFER_SIZE = new ChannelOption<Integer>(
|
||||
"SYSTEM_SEND_BUFFER_SIZE");
|
||||
|
||||
/**
|
||||
* Gets {@link KindUDT#ACCEPTOR} channel backlog.
|
||||
*/
|
||||
int getBacklog();
|
||||
|
||||
/**
|
||||
* Gets {@link OptionUDT#Protocol_Receive_Buffer_Size}
|
||||
*/
|
||||
int getProtocolReceiveBufferSize();
|
||||
|
||||
/**
|
||||
* Gets {@link OptionUDT#Protocol_Send_Buffer_Size}
|
||||
*/
|
||||
int getProtocolSendBufferSize();
|
||||
|
||||
/**
|
||||
* Gets the {@link ChannelOption#SO_RCVBUF} option.
|
||||
*/
|
||||
int getReceiveBufferSize();
|
||||
|
||||
/**
|
||||
* Gets the {@link ChannelOption#SO_SNDBUF} option.
|
||||
*/
|
||||
int getSendBufferSize();
|
||||
|
||||
/**
|
||||
* Gets the {@link ChannelOption#SO_LINGER} option.
|
||||
*/
|
||||
int getSoLinger();
|
||||
|
||||
/**
|
||||
* Gets {@link OptionUDT#System_Receive_Buffer_Size}
|
||||
*/
|
||||
int getSystemReceiveBufferSize();
|
||||
|
||||
/**
|
||||
* Gets {@link OptionUDT#System_Send_Buffer_Size}
|
||||
*/
|
||||
int getSystemSendBufferSize();
|
||||
|
||||
/**
|
||||
* Gets the {@link ChannelOption#SO_REUSEADDR} option.
|
||||
*/
|
||||
boolean isReuseAddress();
|
||||
|
||||
/**
|
||||
* Sets {@link KindUDT#ACCEPTOR} channel backlog.
|
||||
*/
|
||||
UdtChannelConfig setBacklog(int backlog);
|
||||
|
||||
/**
|
||||
* Sets {@link OptionUDT#Protocol_Receive_Buffer_Size}
|
||||
*/
|
||||
UdtChannelConfig setProtocolReceiveBufferSize(int size);
|
||||
|
||||
/**
|
||||
* Sets {@link OptionUDT#Protocol_Send_Buffer_Size}
|
||||
*/
|
||||
UdtChannelConfig setProtocolSendBufferSize(int size);
|
||||
|
||||
/**
|
||||
* Sets the {@link ChannelOption#SO_RCVBUF} option.
|
||||
*/
|
||||
UdtChannelConfig setReceiveBufferSize(int receiveBufferSize);
|
||||
|
||||
/**
|
||||
* Sets the {@link ChannelOption#SO_REUSEADDR} option.
|
||||
*/
|
||||
UdtChannelConfig setReuseAddress(boolean reuseAddress);
|
||||
|
||||
/**
|
||||
* Sets the {@link ChannelOption#SO_SNDBUF} option.
|
||||
*/
|
||||
UdtChannelConfig setSendBufferSize(int sendBufferSize);
|
||||
|
||||
/**
|
||||
* Sets the {@link ChannelOption#SO_LINGER} option.
|
||||
*/
|
||||
UdtChannelConfig setSoLinger(int soLinger);
|
||||
|
||||
/**
|
||||
* Sets {@link OptionUDT#System_Receive_Buffer_Size}
|
||||
*/
|
||||
UdtChannelConfig setSystemReceiveBufferSize(int size);
|
||||
|
||||
/**
|
||||
* Sets {@link OptionUDT#System_Send_Buffer_Size}
|
||||
*/
|
||||
UdtChannelConfig setSystemSendBufferSize(int size);
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.DefaultByteBufHolder;
|
||||
import io.netty.transport.udt.nio.NioUdtProvider;
|
||||
|
||||
import com.barchart.udt.TypeUDT;
|
||||
|
||||
/**
|
||||
* The message container that is used for {@link TypeUDT#DATAGRAM} messages.
|
||||
* @see {@link NioUdtProvider#MESSAGE_CONNECTOR}
|
||||
* @see {@link NioUdtProvider#MESSAGE_RENDEZVOUS}
|
||||
*/
|
||||
public final class UdtMessage extends DefaultByteBufHolder {
|
||||
|
||||
public UdtMessage(final ByteBuf data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UdtMessage copy() {
|
||||
return new UdtMessage(data().copy());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.nio;
|
||||
|
||||
import static java.nio.channels.SelectionKey.*;
|
||||
import io.netty.buffer.MessageBuf;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.socket.nio.AbstractNioMessageChannel;
|
||||
import io.netty.logging.InternalLogger;
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
import io.netty.transport.udt.DefaultUdtChannelConfig;
|
||||
import io.netty.transport.udt.UdtChannel;
|
||||
import io.netty.transport.udt.UdtChannelConfig;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
|
||||
import com.barchart.udt.TypeUDT;
|
||||
import com.barchart.udt.nio.ServerSocketChannelUDT;
|
||||
|
||||
/**
|
||||
* Common base for Netty Byte/Message UDT Stream/Datagram acceptors.
|
||||
*/
|
||||
public abstract class NioUdtAcceptorChannel extends AbstractNioMessageChannel
|
||||
implements UdtChannel {
|
||||
|
||||
protected static final InternalLogger logger = InternalLoggerFactory
|
||||
.getInstance(NioUdtAcceptorChannel.class);
|
||||
|
||||
private final UdtChannelConfig config;
|
||||
|
||||
protected NioUdtAcceptorChannel(final ServerSocketChannelUDT channelUDT) {
|
||||
super(null, channelUDT.socketUDT().id(), channelUDT, OP_ACCEPT);
|
||||
try {
|
||||
channelUDT.configureBlocking(false);
|
||||
config = new DefaultUdtChannelConfig(this, channelUDT, true);
|
||||
} catch (final Exception e) {
|
||||
try {
|
||||
channelUDT.close();
|
||||
} catch (final Exception e2) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Failed to close channel.", e2);
|
||||
}
|
||||
}
|
||||
throw new ChannelException("Failed configure channel.", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected NioUdtAcceptorChannel(final TypeUDT type) {
|
||||
this(NioUdtProvider.newAcceptorChannelUDT(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public UdtChannelConfig config() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doBind(final SocketAddress localAddress) throws Exception {
|
||||
javaChannel().socket().bind(localAddress, config.getBacklog());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doClose() throws Exception {
|
||||
javaChannel().close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doConnect(final SocketAddress remoteAddress,
|
||||
final SocketAddress localAddress) throws Exception {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doDisconnect() throws Exception {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFinishConnect() throws Exception {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int doWriteMessages(final MessageBuf<Object> buf,
|
||||
final boolean lastSpin) throws Exception {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return javaChannel().socket().isBound();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServerSocketChannelUDT javaChannel() {
|
||||
return (ServerSocketChannelUDT) super.javaChannel();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SocketAddress localAddress0() {
|
||||
return javaChannel().socket().getLocalSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress remoteAddress() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SocketAddress remoteAddress0() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.nio;
|
||||
|
||||
import io.netty.buffer.BufType;
|
||||
import io.netty.buffer.MessageBuf;
|
||||
import io.netty.channel.ChannelMetadata;
|
||||
import io.netty.logging.InternalLogger;
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
|
||||
import com.barchart.udt.TypeUDT;
|
||||
import com.barchart.udt.nio.SocketChannelUDT;
|
||||
|
||||
/**
|
||||
* Byte Channel Acceptor for UDT Streams.
|
||||
*/
|
||||
public class NioUdtByteAcceptorChannel extends NioUdtAcceptorChannel {
|
||||
|
||||
private static final InternalLogger logger = InternalLoggerFactory
|
||||
.getInstance(NioUdtByteAcceptorChannel.class);
|
||||
|
||||
private static final ChannelMetadata METADATA = new ChannelMetadata(
|
||||
BufType.BYTE, false);
|
||||
|
||||
public NioUdtByteAcceptorChannel() {
|
||||
super(TypeUDT.STREAM);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int doReadMessages(final MessageBuf<Object> buf) throws Exception {
|
||||
final SocketChannelUDT channelUDT = javaChannel().accept();
|
||||
if (channelUDT == null) {
|
||||
return 0;
|
||||
} else {
|
||||
buf.add(new NioUdtByteConnectorChannel(this, channelUDT.socketUDT()
|
||||
.id(), channelUDT));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelMetadata metadata() {
|
||||
return METADATA;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.nio;
|
||||
|
||||
import static java.nio.channels.SelectionKey.*;
|
||||
import io.netty.buffer.BufType;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelMetadata;
|
||||
import io.netty.channel.socket.nio.AbstractNioByteChannel;
|
||||
import io.netty.logging.InternalLogger;
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
import io.netty.transport.udt.DefaultUdtChannelConfig;
|
||||
import io.netty.transport.udt.UdtChannel;
|
||||
import io.netty.transport.udt.UdtChannelConfig;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.channels.SelectionKey;
|
||||
|
||||
import com.barchart.udt.TypeUDT;
|
||||
import com.barchart.udt.nio.SocketChannelUDT;
|
||||
|
||||
/**
|
||||
* Byte Channel Connector for UDT Streams.
|
||||
*/
|
||||
public class NioUdtByteConnectorChannel extends AbstractNioByteChannel
|
||||
implements UdtChannel {
|
||||
|
||||
private static final InternalLogger logger = InternalLoggerFactory
|
||||
.getInstance(NioUdtByteConnectorChannel.class);
|
||||
|
||||
private static final ChannelMetadata METADATA = new ChannelMetadata(
|
||||
BufType.BYTE, false);
|
||||
|
||||
private final UdtChannelConfig config;
|
||||
|
||||
public NioUdtByteConnectorChannel() {
|
||||
this(TypeUDT.STREAM);
|
||||
}
|
||||
|
||||
public NioUdtByteConnectorChannel(final Channel parent, final Integer id,
|
||||
final SocketChannelUDT channelUDT) {
|
||||
super(parent, id, channelUDT);
|
||||
try {
|
||||
channelUDT.configureBlocking(false);
|
||||
switch (channelUDT.socketUDT().status()) {
|
||||
case INIT:
|
||||
case OPENED:
|
||||
config = new DefaultUdtChannelConfig(this, channelUDT, true);
|
||||
break;
|
||||
default:
|
||||
config = new DefaultUdtChannelConfig(this, channelUDT, false);
|
||||
break;
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
try {
|
||||
channelUDT.close();
|
||||
} catch (final Exception e2) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Failed to close channel.", e2);
|
||||
}
|
||||
}
|
||||
throw new ChannelException("Failed to configure channel.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public NioUdtByteConnectorChannel(final SocketChannelUDT channelUDT) {
|
||||
this(null, channelUDT.socketUDT().id(), channelUDT);
|
||||
}
|
||||
|
||||
public NioUdtByteConnectorChannel(final TypeUDT type) {
|
||||
this(NioUdtProvider.newConnectorChannelUDT(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public UdtChannelConfig config() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doBind(final SocketAddress localAddress) throws Exception {
|
||||
javaChannel().bind(localAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doClose() throws Exception {
|
||||
javaChannel().close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doConnect(final SocketAddress remoteAddress,
|
||||
final SocketAddress localAddress) throws Exception {
|
||||
doBind(localAddress);
|
||||
boolean success = false;
|
||||
try {
|
||||
final boolean connected = javaChannel().connect(remoteAddress);
|
||||
if (!connected) {
|
||||
selectionKey().interestOps(
|
||||
selectionKey().interestOps() | OP_CONNECT);
|
||||
}
|
||||
success = true;
|
||||
return connected;
|
||||
} finally {
|
||||
if (!success) {
|
||||
doClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doDisconnect() throws Exception {
|
||||
doClose();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFinishConnect() throws Exception {
|
||||
if (javaChannel().finishConnect()) {
|
||||
selectionKey().interestOps(
|
||||
selectionKey().interestOps() & ~OP_CONNECT);
|
||||
} else {
|
||||
throw new Error(
|
||||
"Provider error: failed to finish connect. Provider library should be upgraded.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int doReadBytes(final ByteBuf byteBuf) throws Exception {
|
||||
return byteBuf.writeBytes(javaChannel(), byteBuf.writableBytes());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int doWriteBytes(final ByteBuf byteBuf, final boolean lastSpin)
|
||||
throws Exception {
|
||||
final int pendingBytes = byteBuf.readableBytes();
|
||||
final int writtenBytes = byteBuf.readBytes(javaChannel(), pendingBytes);
|
||||
final SelectionKey key = selectionKey();
|
||||
final int interestOps = key.interestOps();
|
||||
if (writtenBytes >= pendingBytes) {
|
||||
// wrote the buffer completely - clear OP_WRITE.
|
||||
if ((interestOps & OP_WRITE) != 0) {
|
||||
key.interestOps(interestOps & ~OP_WRITE);
|
||||
}
|
||||
} else {
|
||||
// wrote partial or nothing - ensure OP_WRITE
|
||||
if (writtenBytes > 0 || lastSpin) {
|
||||
if ((interestOps & OP_WRITE) == 0) {
|
||||
key.interestOps(interestOps | OP_WRITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
return writtenBytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
final SocketChannelUDT channelUDT = javaChannel();
|
||||
return channelUDT.isOpen() && channelUDT.isConnectFinished();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SocketChannelUDT javaChannel() {
|
||||
return (SocketChannelUDT) super.javaChannel();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SocketAddress localAddress0() {
|
||||
return javaChannel().socket().getLocalSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelMetadata metadata() {
|
||||
return METADATA;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SocketAddress remoteAddress0() {
|
||||
return javaChannel().socket().getRemoteSocketAddress();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.nio;
|
||||
|
||||
import io.netty.logging.InternalLogger;
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
import io.netty.transport.udt.UdtChannel;
|
||||
|
||||
import com.barchart.udt.TypeUDT;
|
||||
|
||||
/**
|
||||
* Byte Channel Rendezvous for UDT Streams.
|
||||
*/
|
||||
public class NioUdtByteRendezvousChannel extends NioUdtByteConnectorChannel
|
||||
implements UdtChannel {
|
||||
|
||||
private static final InternalLogger logger = InternalLoggerFactory
|
||||
.getInstance(NioUdtByteRendezvousChannel.class);
|
||||
|
||||
public NioUdtByteRendezvousChannel() {
|
||||
super(NioUdtProvider.newRendezvousChannelUDT(TypeUDT.STREAM));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.nio;
|
||||
|
||||
import io.netty.buffer.BufType;
|
||||
import io.netty.buffer.MessageBuf;
|
||||
import io.netty.channel.ChannelMetadata;
|
||||
import io.netty.logging.InternalLogger;
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
|
||||
import com.barchart.udt.TypeUDT;
|
||||
import com.barchart.udt.nio.SocketChannelUDT;
|
||||
|
||||
/**
|
||||
* Message Channel Acceptor for UDT Datagrams.
|
||||
*/
|
||||
public class NioUdtMessageAcceptorChannel extends NioUdtAcceptorChannel {
|
||||
|
||||
private static final InternalLogger logger = InternalLoggerFactory
|
||||
.getInstance(NioUdtMessageAcceptorChannel.class);
|
||||
|
||||
private static final ChannelMetadata METADATA = new ChannelMetadata(
|
||||
BufType.MESSAGE, false);
|
||||
|
||||
public NioUdtMessageAcceptorChannel() {
|
||||
super(TypeUDT.DATAGRAM);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int doReadMessages(final MessageBuf<Object> buf) throws Exception {
|
||||
final SocketChannelUDT channelUDT = javaChannel().accept();
|
||||
if (channelUDT == null) {
|
||||
return 0;
|
||||
} else {
|
||||
buf.add(new NioUdtMessageConnectorChannel(this, channelUDT
|
||||
.socketUDT().id(), channelUDT));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelMetadata metadata() {
|
||||
return METADATA;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.nio;
|
||||
|
||||
import static java.nio.channels.SelectionKey.*;
|
||||
import io.netty.buffer.BufType;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.MessageBuf;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelMetadata;
|
||||
import io.netty.channel.socket.nio.AbstractNioMessageChannel;
|
||||
import io.netty.logging.InternalLogger;
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
import io.netty.transport.udt.DefaultUdtChannelConfig;
|
||||
import io.netty.transport.udt.UdtChannel;
|
||||
import io.netty.transport.udt.UdtChannelConfig;
|
||||
import io.netty.transport.udt.UdtMessage;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.channels.SelectionKey;
|
||||
|
||||
import com.barchart.udt.TypeUDT;
|
||||
import com.barchart.udt.nio.SocketChannelUDT;
|
||||
|
||||
/**
|
||||
* Message Connector for UDT Datagrams.
|
||||
* <p>
|
||||
* Note: send/receive must use {@link UdtMessage} in the pipeline
|
||||
*/
|
||||
public class NioUdtMessageConnectorChannel extends AbstractNioMessageChannel
|
||||
implements UdtChannel {
|
||||
|
||||
private static final InternalLogger logger = InternalLoggerFactory
|
||||
.getInstance(NioUdtMessageConnectorChannel.class);
|
||||
|
||||
private static final ChannelMetadata METADATA = new ChannelMetadata(
|
||||
BufType.MESSAGE, false);
|
||||
|
||||
private final UdtChannelConfig config;
|
||||
|
||||
public NioUdtMessageConnectorChannel() {
|
||||
this(TypeUDT.DATAGRAM);
|
||||
}
|
||||
|
||||
public NioUdtMessageConnectorChannel(final Channel parent,
|
||||
final Integer id, final SocketChannelUDT channelUDT) {
|
||||
super(parent, id, channelUDT, OP_READ);
|
||||
try {
|
||||
channelUDT.configureBlocking(false);
|
||||
switch (channelUDT.socketUDT().status()) {
|
||||
case INIT:
|
||||
case OPENED:
|
||||
config = new DefaultUdtChannelConfig(this, channelUDT, true);
|
||||
break;
|
||||
default:
|
||||
config = new DefaultUdtChannelConfig(this, channelUDT, false);
|
||||
break;
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
try {
|
||||
channelUDT.close();
|
||||
} catch (final Exception e2) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Failed to close channel.", e2);
|
||||
}
|
||||
}
|
||||
throw new ChannelException("Failed to configure channel.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public NioUdtMessageConnectorChannel(final SocketChannelUDT channelUDT) {
|
||||
this(null, channelUDT.socketUDT().id(), channelUDT);
|
||||
}
|
||||
|
||||
public NioUdtMessageConnectorChannel(final TypeUDT type) {
|
||||
this(NioUdtProvider.newConnectorChannelUDT(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public UdtChannelConfig config() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doBind(final SocketAddress localAddress) throws Exception {
|
||||
javaChannel().bind(localAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doClose() throws Exception {
|
||||
javaChannel().close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doConnect(final SocketAddress remoteAddress,
|
||||
final SocketAddress localAddress) throws Exception {
|
||||
doBind(localAddress);
|
||||
boolean success = false;
|
||||
try {
|
||||
final boolean connected = javaChannel().connect(remoteAddress);
|
||||
if (!connected) {
|
||||
selectionKey().interestOps(
|
||||
selectionKey().interestOps() | OP_CONNECT);
|
||||
}
|
||||
success = true;
|
||||
return connected;
|
||||
} finally {
|
||||
if (!success) {
|
||||
doClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doDisconnect() throws Exception {
|
||||
doClose();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFinishConnect() throws Exception {
|
||||
if (javaChannel().finishConnect()) {
|
||||
selectionKey().interestOps(
|
||||
selectionKey().interestOps() & ~OP_CONNECT);
|
||||
} else {
|
||||
throw new Error(
|
||||
"Provider error: failed to finish connect. Provider library should be upgraded.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int doReadMessages(final MessageBuf<Object> buf) throws Exception {
|
||||
|
||||
final int maximumMessageSize = config.getReceiveBufferSize();
|
||||
|
||||
final ByteBuf byteBuf = config.getAllocator().directBuffer(
|
||||
maximumMessageSize);
|
||||
|
||||
final int receivedMessageSize = byteBuf.writeBytes(javaChannel(),
|
||||
maximumMessageSize);
|
||||
|
||||
if (receivedMessageSize <= 0) {
|
||||
byteBuf.free();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (receivedMessageSize >= maximumMessageSize) {
|
||||
javaChannel().close();
|
||||
throw new ChannelException(
|
||||
"Invalid config : increase receive buffer size to avoid message truncation");
|
||||
}
|
||||
|
||||
// delivers a message
|
||||
buf.add(new UdtMessage(byteBuf));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int doWriteMessages(final MessageBuf<Object> messageQueue,
|
||||
final boolean lastSpin) throws Exception {
|
||||
|
||||
// expects a message
|
||||
final UdtMessage message = (UdtMessage) messageQueue.peek();
|
||||
|
||||
final ByteBuf byteBuf = message.data();
|
||||
|
||||
final int messageSize = byteBuf.readableBytes();
|
||||
|
||||
final long writtenBytes;
|
||||
if (byteBuf.nioBufferCount() == 1) {
|
||||
writtenBytes = javaChannel().write(byteBuf.nioBuffer());
|
||||
} else {
|
||||
writtenBytes = javaChannel().write(byteBuf.nioBuffers());
|
||||
}
|
||||
|
||||
final SelectionKey key = selectionKey();
|
||||
final int interestOps = key.interestOps();
|
||||
|
||||
// did not write the message
|
||||
if (writtenBytes <= 0 && messageSize > 0) {
|
||||
if (lastSpin) {
|
||||
if ((interestOps & OP_WRITE) == 0) {
|
||||
key.interestOps(interestOps | OP_WRITE);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// wrote message completely
|
||||
if (writtenBytes != messageSize) {
|
||||
throw new Error(
|
||||
"Provider error: failed to write message. Provider library should be upgraded.");
|
||||
}
|
||||
|
||||
// wrote the message queue completely - clear OP_WRITE.
|
||||
if (messageQueue.isEmpty()) {
|
||||
if ((interestOps & OP_WRITE) != 0) {
|
||||
key.interestOps(interestOps & ~OP_WRITE);
|
||||
}
|
||||
}
|
||||
|
||||
messageQueue.remove();
|
||||
|
||||
message.free();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
final SocketChannelUDT channelUDT = javaChannel();
|
||||
return channelUDT.isOpen() && channelUDT.isConnectFinished();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SocketChannelUDT javaChannel() {
|
||||
return (SocketChannelUDT) super.javaChannel();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SocketAddress localAddress0() {
|
||||
return javaChannel().socket().getLocalSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelMetadata metadata() {
|
||||
return METADATA;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SocketAddress remoteAddress0() {
|
||||
return javaChannel().socket().getRemoteSocketAddress();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.nio;
|
||||
|
||||
import io.netty.logging.InternalLogger;
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
import io.netty.transport.udt.UdtChannel;
|
||||
import io.netty.transport.udt.UdtMessage;
|
||||
|
||||
import com.barchart.udt.TypeUDT;
|
||||
|
||||
/**
|
||||
* Message Rendezvous for UDT Datagrams.
|
||||
* <p>
|
||||
* Note: send/receive must use {@link UdtMessage} in the pipeline
|
||||
*/
|
||||
public class NioUdtMessageRendezvousChannel extends
|
||||
NioUdtMessageConnectorChannel implements UdtChannel {
|
||||
|
||||
private static final InternalLogger logger = InternalLoggerFactory
|
||||
.getInstance(NioUdtMessageConnectorChannel.class);
|
||||
|
||||
public NioUdtMessageRendezvousChannel() {
|
||||
super(NioUdtProvider.newRendezvousChannelUDT(TypeUDT.DATAGRAM));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.nio;
|
||||
|
||||
import io.netty.bootstrap.AbstractBootstrap.ChannelFactory;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.logging.InternalLogger;
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
import io.netty.transport.udt.UdtChannel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.spi.SelectorProvider;
|
||||
|
||||
import com.barchart.udt.SocketUDT;
|
||||
import com.barchart.udt.TypeUDT;
|
||||
import com.barchart.udt.nio.ChannelUDT;
|
||||
import com.barchart.udt.nio.KindUDT;
|
||||
import com.barchart.udt.nio.RendezvousChannelUDT;
|
||||
import com.barchart.udt.nio.SelectorProviderUDT;
|
||||
import com.barchart.udt.nio.ServerSocketChannelUDT;
|
||||
import com.barchart.udt.nio.SocketChannelUDT;
|
||||
|
||||
/**
|
||||
* UDT NIO components provider:
|
||||
* <p>
|
||||
* Provides {@link ChannelFactory} for UDT channels.
|
||||
* <p>
|
||||
* Provides {@link SelectorProvider} for UDT channels.
|
||||
*/
|
||||
public final class NioUdtProvider implements ChannelFactory {
|
||||
|
||||
private static final InternalLogger logger = InternalLoggerFactory
|
||||
.getInstance(NioUdtProvider.class);
|
||||
|
||||
/**
|
||||
* {@link ChannelFactory} for UDT Byte Acceptor. See {@link TypeUDT#STREAM}
|
||||
* and {@link KindUDT#ACCEPTOR}.
|
||||
*/
|
||||
public static final ChannelFactory BYTE_ACCEPTOR = new NioUdtProvider(
|
||||
TypeUDT.STREAM, KindUDT.ACCEPTOR);
|
||||
|
||||
/**
|
||||
* {@link ChannelFactory} for UDT Byte Connector. See {@link TypeUDT#STREAM}
|
||||
* and {@link KindUDT#CONNECTOR}.
|
||||
*/
|
||||
public static final ChannelFactory BYTE_CONNECTOR = new NioUdtProvider(
|
||||
TypeUDT.STREAM, KindUDT.CONNECTOR);
|
||||
|
||||
/**
|
||||
* {@link SelectorProvider} for UDT Byte channels. See
|
||||
* {@link TypeUDT#STREAM}.
|
||||
*/
|
||||
public static final SelectorProvider BYTE_PROVIDER = SelectorProviderUDT.STREAM;
|
||||
|
||||
/**
|
||||
* {@link ChannelFactory} for UDT Byte Rendezvous. See
|
||||
* {@link TypeUDT#STREAM} and {@link KindUDT#RENDEZVOUS}.
|
||||
*/
|
||||
public static final ChannelFactory BYTE_RENDEZVOUS = new NioUdtProvider(
|
||||
TypeUDT.STREAM, KindUDT.RENDEZVOUS);
|
||||
|
||||
/**
|
||||
* {@link ChannelFactory} for UDT Message Acceptor. See
|
||||
* {@link TypeUDT#DATAGRAM} and {@link KindUDT#ACCEPTOR}.
|
||||
*/
|
||||
public static final ChannelFactory MESSAGE_ACCEPTOR = new NioUdtProvider(
|
||||
TypeUDT.DATAGRAM, KindUDT.ACCEPTOR);
|
||||
|
||||
/**
|
||||
* {@link ChannelFactory} for UDT Message Connector. See
|
||||
* {@link TypeUDT#DATAGRAM} and {@link KindUDT#CONNECTOR}.
|
||||
*/
|
||||
public static final ChannelFactory MESSAGE_CONNECTOR = new NioUdtProvider(
|
||||
TypeUDT.DATAGRAM, KindUDT.CONNECTOR);
|
||||
|
||||
/**
|
||||
* {@link SelectorProvider} for UDT Message channels. See
|
||||
* {@link TypeUDT#DATAGRAM}.
|
||||
*/
|
||||
public static final SelectorProvider MESSAGE_PROVIDER = SelectorProviderUDT.DATAGRAM;
|
||||
|
||||
/**
|
||||
* {@link ChannelFactory} for UDT Message Rendezvous. See
|
||||
* {@link TypeUDT#DATAGRAM} and {@link KindUDT#RENDEZVOUS}.
|
||||
*/
|
||||
public static final ChannelFactory MESSAGE_RENDEZVOUS = new NioUdtProvider(
|
||||
TypeUDT.DATAGRAM, KindUDT.RENDEZVOUS);
|
||||
|
||||
/**
|
||||
* Expose underlying {@link ChannelUDT} for debugging and monitoring.
|
||||
* <p>
|
||||
* @return underlying {@link ChannelUDT} or null, if parameter is not
|
||||
* {@link UdtChannel}
|
||||
*/
|
||||
public static ChannelUDT channelUDT(final Channel channel) {
|
||||
// bytes
|
||||
if (channel instanceof NioUdtByteAcceptorChannel) {
|
||||
return ((NioUdtByteAcceptorChannel) channel).javaChannel();
|
||||
}
|
||||
if (channel instanceof NioUdtByteConnectorChannel) {
|
||||
return ((NioUdtByteConnectorChannel) channel).javaChannel();
|
||||
}
|
||||
if (channel instanceof NioUdtByteRendezvousChannel) {
|
||||
return ((NioUdtByteRendezvousChannel) channel).javaChannel();
|
||||
}
|
||||
// message
|
||||
if (channel instanceof NioUdtMessageAcceptorChannel) {
|
||||
return ((NioUdtMessageAcceptorChannel) channel).javaChannel();
|
||||
}
|
||||
if (channel instanceof NioUdtMessageConnectorChannel) {
|
||||
return ((NioUdtMessageConnectorChannel) channel).javaChannel();
|
||||
}
|
||||
if (channel instanceof NioUdtMessageRendezvousChannel) {
|
||||
return ((NioUdtMessageRendezvousChannel) channel).javaChannel();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience factory for {@link KindUDT#ACCEPTOR} channels.
|
||||
*/
|
||||
protected static ServerSocketChannelUDT newAcceptorChannelUDT(
|
||||
final TypeUDT type) {
|
||||
try {
|
||||
return SelectorProviderUDT.from(type).openServerSocketChannel();
|
||||
} catch (final IOException e) {
|
||||
throw new ChannelException("Failed to open channel");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience factory for {@link KindUDT#CONNECTOR} channels.
|
||||
*/
|
||||
protected static SocketChannelUDT newConnectorChannelUDT(final TypeUDT type) {
|
||||
try {
|
||||
return SelectorProviderUDT.from(type).openSocketChannel();
|
||||
} catch (final IOException e) {
|
||||
throw new ChannelException("Failed to open channel");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience factory for {@link KindUDT#RENDEZVOUS} channels.
|
||||
*/
|
||||
protected static RendezvousChannelUDT newRendezvousChannelUDT(
|
||||
final TypeUDT type) {
|
||||
try {
|
||||
return SelectorProviderUDT.from(type).openRendezvousChannel();
|
||||
} catch (final IOException e) {
|
||||
throw new ChannelException("Failed to open channel");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose underlying {@link SocketUDT} for debugging and monitoring.
|
||||
* <p>
|
||||
* @return underlying {@link SocketUDT} or null, if parameter is not
|
||||
* {@link UdtChannel}
|
||||
*/
|
||||
public static SocketUDT socketUDT(final Channel channel) {
|
||||
final ChannelUDT channelUDT = channelUDT(channel);
|
||||
if (channelUDT == null) {
|
||||
return null;
|
||||
} else {
|
||||
return channelUDT.socketUDT();
|
||||
}
|
||||
}
|
||||
|
||||
private final KindUDT kind;
|
||||
private final TypeUDT type;
|
||||
|
||||
/**
|
||||
* {@link ChannelFactory} for given {@link TypeUDT} and {@link KindUDT}
|
||||
*/
|
||||
private NioUdtProvider(final TypeUDT type, final KindUDT kind) {
|
||||
this.type = type;
|
||||
this.kind = kind;
|
||||
}
|
||||
|
||||
/**
|
||||
* UDT Channel Kind. See {@link KindUDT}
|
||||
*/
|
||||
public KindUDT kind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce new {@link UdtChannel} based on factory {@link #kind()} and
|
||||
* {@link #type()}
|
||||
*/
|
||||
@Override
|
||||
public UdtChannel newChannel() {
|
||||
switch (kind) {
|
||||
case ACCEPTOR:
|
||||
switch (type) {
|
||||
case DATAGRAM:
|
||||
return new NioUdtMessageAcceptorChannel();
|
||||
case STREAM:
|
||||
return new NioUdtByteAcceptorChannel();
|
||||
default:
|
||||
throw new IllegalStateException("wrong type=" + type);
|
||||
}
|
||||
case CONNECTOR:
|
||||
switch (type) {
|
||||
case DATAGRAM:
|
||||
return new NioUdtMessageConnectorChannel();
|
||||
case STREAM:
|
||||
return new NioUdtByteConnectorChannel();
|
||||
default:
|
||||
throw new IllegalStateException("wrong type=" + type);
|
||||
}
|
||||
case RENDEZVOUS:
|
||||
switch (type) {
|
||||
case DATAGRAM:
|
||||
return new NioUdtMessageRendezvousChannel();
|
||||
case STREAM:
|
||||
return new NioUdtByteRendezvousChannel();
|
||||
default:
|
||||
throw new IllegalStateException("wrong type=" + type);
|
||||
}
|
||||
default:
|
||||
throw new IllegalStateException("wrong kind=" + kind);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* UDT Socket Type. See {@link TypeUDT}
|
||||
*/
|
||||
public TypeUDT type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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.
|
||||
*/
|
||||
/**
|
||||
* UDT Transport for NIO Channels.
|
||||
* <p>
|
||||
* @see /netty/example/src/main/java/io/netty/example/udt
|
||||
*/
|
||||
package io.netty.transport.udt.nio;
|
||||
|
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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.
|
||||
*/
|
||||
/**
|
||||
* UDT Transport for OIO Channels.
|
||||
* <p>
|
||||
* @see /netty/example/src/main/java/io/netty/example/udt
|
||||
*/
|
||||
package io.netty.transport.udt.oio;
|
||||
|
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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.
|
||||
*/
|
||||
/**
|
||||
* UDT Transport.
|
||||
* <p>
|
||||
* @see /netty/example/src/main/java/io/netty/example/udt
|
||||
*/
|
||||
package io.netty.transport.udt;
|
||||
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.bench;
|
||||
|
||||
import io.netty.transport.udt.util.CaliperBench;
|
||||
import io.netty.transport.udt.util.CaliperRunner;
|
||||
import io.netty.transport.udt.util.TrafficControl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* perform two way native udt socket send/recv
|
||||
*/
|
||||
public abstract class BenchXfer extends CaliperBench {
|
||||
|
||||
/** introduce network latency */
|
||||
protected static List<String> latencyList() {
|
||||
if (TrafficControl.isAvailable()) {
|
||||
return CaliperRunner.valueList("0,10,30");
|
||||
} else {
|
||||
return CaliperRunner.valueList("0");
|
||||
}
|
||||
}
|
||||
|
||||
/** verify different message sizes */
|
||||
protected static List<String> messageList() {
|
||||
return CaliperRunner
|
||||
.valueList("500,1500,3000,5000,10000,20000,50000,100000");
|
||||
}
|
||||
|
||||
/** benchmark run time per each configuration */
|
||||
protected static List<String> durationList() {
|
||||
return CaliperRunner.valueList("30000");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* UDT Benchmarks
|
||||
*/
|
||||
package io.netty.transport.udt.bench;
|
||||
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.bench.xfer;
|
||||
|
||||
import io.netty.transport.udt.bench.BenchXfer;
|
||||
import io.netty.transport.udt.util.CaliperRunner;
|
||||
import io.netty.transport.udt.util.TrafficControl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.caliper.Param;
|
||||
|
||||
/**
|
||||
* perform two way native TCP socket send/recv
|
||||
*/
|
||||
public class TcpNative extends BenchXfer {
|
||||
|
||||
@Param
|
||||
private volatile int latency;
|
||||
|
||||
protected static List<String> latencyValues() {
|
||||
return BenchXfer.latencyList();
|
||||
}
|
||||
|
||||
@Param
|
||||
private volatile int message;
|
||||
|
||||
protected static List<String> messageValues() {
|
||||
return BenchXfer.messageList();
|
||||
}
|
||||
|
||||
@Param
|
||||
private volatile int duration;
|
||||
|
||||
protected static List<String> durationValues() {
|
||||
return BenchXfer.durationList();
|
||||
}
|
||||
|
||||
public void timeRun(final int reps) throws Exception {
|
||||
log.info("init");
|
||||
|
||||
TrafficControl.delay(latency);
|
||||
|
||||
TrafficControl.delay(0);
|
||||
|
||||
log.info("done");
|
||||
}
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
CaliperRunner.execute(TcpNative.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.bench.xfer;
|
||||
|
||||
import static io.netty.transport.udt.util.UnitHelp.*;
|
||||
import io.netty.transport.udt.bench.BenchXfer;
|
||||
import io.netty.transport.udt.util.CaliperRunner;
|
||||
import io.netty.transport.udt.util.TrafficControl;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import com.barchart.udt.SocketUDT;
|
||||
import com.barchart.udt.StatusUDT;
|
||||
import com.barchart.udt.TypeUDT;
|
||||
import com.google.caliper.Param;
|
||||
|
||||
/**
|
||||
* perform two way native UDT socket send/recv
|
||||
*/
|
||||
public class UdtNative extends BenchXfer {
|
||||
|
||||
@Param
|
||||
private volatile int latency;
|
||||
|
||||
protected static List<String> latencyValues() {
|
||||
return BenchXfer.latencyList();
|
||||
}
|
||||
|
||||
@Param
|
||||
private volatile int message;
|
||||
|
||||
protected static List<String> messageValues() {
|
||||
return BenchXfer.messageList();
|
||||
}
|
||||
|
||||
@Param
|
||||
private volatile int duration;
|
||||
|
||||
protected static List<String> durationValues() {
|
||||
return BenchXfer.durationList();
|
||||
}
|
||||
|
||||
private volatile SocketUDT peer1;
|
||||
private volatile SocketUDT peer2;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
log.info("init");
|
||||
|
||||
TrafficControl.delay(latency);
|
||||
|
||||
final InetSocketAddress addr1 = localSocketAddress();
|
||||
final InetSocketAddress addr2 = localSocketAddress();
|
||||
|
||||
peer1 = new SocketUDT(TypeUDT.DATAGRAM);
|
||||
peer2 = new SocketUDT(TypeUDT.DATAGRAM);
|
||||
|
||||
peer1.setBlocking(false);
|
||||
peer2.setBlocking(false);
|
||||
|
||||
peer1.setRendezvous(true);
|
||||
peer2.setRendezvous(true);
|
||||
|
||||
peer1.bind(addr1);
|
||||
peer2.bind(addr2);
|
||||
|
||||
socketAwait(peer1, StatusUDT.OPENED);
|
||||
socketAwait(peer2, StatusUDT.OPENED);
|
||||
|
||||
peer1.connect(addr2);
|
||||
peer2.connect(addr1);
|
||||
|
||||
socketAwait(peer1, StatusUDT.CONNECTED);
|
||||
socketAwait(peer2, StatusUDT.CONNECTED);
|
||||
|
||||
peer1.setBlocking(true);
|
||||
peer2.setBlocking(true);
|
||||
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
|
||||
peer1.setBlocking(false);
|
||||
peer2.setBlocking(false);
|
||||
|
||||
peer1.close();
|
||||
peer2.close();
|
||||
|
||||
socketAwait(peer1, StatusUDT.CLOSED, StatusUDT.BROKEN);
|
||||
socketAwait(peer2, StatusUDT.CLOSED, StatusUDT.BROKEN);
|
||||
|
||||
TrafficControl.delay(0);
|
||||
|
||||
log.info("done");
|
||||
}
|
||||
|
||||
/** benchmark invocation */
|
||||
public void timeMain(final int reps) throws Exception {
|
||||
|
||||
final int threadCount = 4;
|
||||
|
||||
final CountDownLatch completion = new CountDownLatch(threadCount);
|
||||
|
||||
final AtomicBoolean isOn = new AtomicBoolean(true);
|
||||
|
||||
final Runnable sendPeer1 = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (isOn.get()) {
|
||||
runCore();
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
log.error("", e);
|
||||
} finally {
|
||||
completion.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
final ByteBuffer buffer = ByteBuffer.allocateDirect(message);
|
||||
|
||||
long sequence;
|
||||
|
||||
void runCore() throws Exception {
|
||||
buffer.rewind();
|
||||
buffer.putLong(0, sequence++);
|
||||
final int count = peer1.send(buffer);
|
||||
if (count != message) {
|
||||
throw new Exception("count");
|
||||
}
|
||||
measure().rate().mark(count);
|
||||
}
|
||||
};
|
||||
|
||||
final Runnable sendPeer2 = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (isOn.get()) {
|
||||
runCore();
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
log.error("", e);
|
||||
} finally {
|
||||
completion.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
final ByteBuffer buffer = ByteBuffer.allocateDirect(message);
|
||||
|
||||
long sequence;
|
||||
|
||||
void runCore() throws Exception {
|
||||
buffer.rewind();
|
||||
buffer.putLong(0, sequence++);
|
||||
final int count = peer2.send(buffer);
|
||||
if (count != message) {
|
||||
throw new Exception("count");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
final Runnable recvPeer1 = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (isOn.get()) {
|
||||
runCore();
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
log.error("", e);
|
||||
} finally {
|
||||
completion.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
final ByteBuffer buffer = ByteBuffer.allocateDirect(message);
|
||||
|
||||
long sequence;
|
||||
|
||||
void runCore() throws Exception {
|
||||
buffer.rewind();
|
||||
final int count = peer1.receive(buffer);
|
||||
if (count != message) {
|
||||
throw new Exception("count");
|
||||
}
|
||||
if (this.sequence++ != buffer.getLong(0)) {
|
||||
throw new Exception("sequence");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
final Runnable recvPeer2 = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (isOn.get()) {
|
||||
runCore();
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
log.error("", e);
|
||||
} finally {
|
||||
completion.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
final ByteBuffer buffer = ByteBuffer.allocateDirect(message);
|
||||
|
||||
long sequence;
|
||||
|
||||
void runCore() throws Exception {
|
||||
buffer.rewind();
|
||||
final int count = peer2.receive(buffer);
|
||||
if (count != message) {
|
||||
throw new Exception("count");
|
||||
}
|
||||
if (this.sequence++ != buffer.getLong(0)) {
|
||||
throw new Exception("sequence");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
final ExecutorService executor = Executors
|
||||
.newFixedThreadPool(threadCount);
|
||||
|
||||
executor.submit(recvPeer1);
|
||||
executor.submit(recvPeer2);
|
||||
executor.submit(sendPeer1);
|
||||
executor.submit(sendPeer2);
|
||||
|
||||
markWait(duration);
|
||||
|
||||
isOn.set(false);
|
||||
|
||||
completion.await();
|
||||
|
||||
executor.shutdownNow();
|
||||
}
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
CaliperRunner.execute(UdtNative.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.bench.xfer;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
import io.netty.logging.Slf4JLoggerFactory;
|
||||
import io.netty.transport.udt.util.BootHelp;
|
||||
import io.netty.transport.udt.util.CustomReporter;
|
||||
import io.netty.transport.udt.util.EchoMessageHandler;
|
||||
import io.netty.transport.udt.util.TrafficControl;
|
||||
import io.netty.transport.udt.util.UnitHelp;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.yammer.metrics.Metrics;
|
||||
import com.yammer.metrics.core.Counter;
|
||||
import com.yammer.metrics.core.Meter;
|
||||
|
||||
/**
|
||||
* perform two way netty send/recv
|
||||
*/
|
||||
public final class UdtNetty {
|
||||
|
||||
private UdtNetty() {
|
||||
}
|
||||
|
||||
static final Logger log = LoggerFactory.getLogger(UdtNetty.class);
|
||||
|
||||
/**
|
||||
* use slf4j provider for io.netty.logging.InternalLogger
|
||||
*/
|
||||
static {
|
||||
final InternalLoggerFactory defaultFactory = new Slf4JLoggerFactory();
|
||||
InternalLoggerFactory.setDefaultFactory(defaultFactory);
|
||||
log.info("InternalLoggerFactory={}", InternalLoggerFactory
|
||||
.getDefaultFactory().getClass().getName());
|
||||
}
|
||||
|
||||
/** benchmark duration */
|
||||
static final int time = 10 * 60 * 1000;
|
||||
|
||||
/** transfer chunk size */
|
||||
static final int size = 64 * 1024;
|
||||
|
||||
static final Counter benchTime = Metrics.newCounter(UdtNetty.class,
|
||||
"bench time");
|
||||
|
||||
static final Counter benchSize = Metrics.newCounter(UdtNetty.class,
|
||||
"bench size");
|
||||
|
||||
static {
|
||||
benchTime.inc(time);
|
||||
benchSize.inc(size);
|
||||
}
|
||||
|
||||
static final Meter rate = Metrics.newMeter(UdtNetty.class, "rate",
|
||||
"bytes", TimeUnit.SECONDS);
|
||||
|
||||
static {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
TrafficControl.delay(0);
|
||||
} catch (final Exception e) {
|
||||
log.error("", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
|
||||
log.info("init");
|
||||
TrafficControl.delay(0);
|
||||
|
||||
final AtomicBoolean isOn = new AtomicBoolean(true);
|
||||
|
||||
final InetSocketAddress addr1 = UnitHelp.localSocketAddress();
|
||||
final InetSocketAddress addr2 = UnitHelp.localSocketAddress();
|
||||
|
||||
final ChannelHandler handler1 = new EchoMessageHandler(rate, size);
|
||||
final ChannelHandler handler2 = new EchoMessageHandler(null, size);
|
||||
|
||||
final Bootstrap peerBoot1 = BootHelp.messagePeerBoot(addr1, addr2,
|
||||
handler1);
|
||||
final Bootstrap peerBoot2 = BootHelp.messagePeerBoot(addr2, addr1,
|
||||
handler2);
|
||||
|
||||
final ChannelFuture peerFuture1 = peerBoot1.connect();
|
||||
final ChannelFuture peerFuture2 = peerBoot2.connect();
|
||||
|
||||
CustomReporter.enable(3, TimeUnit.SECONDS);
|
||||
|
||||
Thread.sleep(time);
|
||||
|
||||
isOn.set(false);
|
||||
|
||||
Thread.sleep(1 * 1000);
|
||||
|
||||
peerFuture1.channel().close().sync();
|
||||
peerFuture2.channel().close().sync();
|
||||
|
||||
Thread.sleep(1 * 1000);
|
||||
|
||||
peerBoot1.shutdown();
|
||||
peerBoot2.shutdown();
|
||||
|
||||
Metrics.defaultRegistry().shutdown();
|
||||
|
||||
TrafficControl.delay(0);
|
||||
log.info("done");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* UDT Transfer Speed Benchmarks
|
||||
*/
|
||||
package io.netty.transport.udt.bench.xfer;
|
||||
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.nio;
|
||||
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
import io.netty.logging.Slf4JLoggerFactory;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* shared test base
|
||||
*/
|
||||
public abstract class TestAny {
|
||||
|
||||
protected static final Logger log = LoggerFactory.getLogger(TestAny.class);
|
||||
|
||||
/**
|
||||
* use slf4j provider for io.netty.logging.InternalLogger
|
||||
*/
|
||||
static {
|
||||
final InternalLoggerFactory defaultFactory = new Slf4JLoggerFactory();
|
||||
InternalLoggerFactory.setDefaultFactory(defaultFactory);
|
||||
log.info("InternalLoggerFactory={}", InternalLoggerFactory
|
||||
.getDefaultFactory().getClass().getName());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.nio;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import io.netty.buffer.BufType;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestNioUdtByteAcceptorChannel extends TestAny {
|
||||
|
||||
/**
|
||||
* verify channel meta data
|
||||
*/
|
||||
@Test
|
||||
public void metadata() throws Exception {
|
||||
|
||||
assertEquals(BufType.BYTE, new NioUdtByteAcceptorChannel().metadata()
|
||||
.bufferType());
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.nio;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import io.netty.buffer.BufType;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestNioUdtByteConnectorChannel extends TestAny {
|
||||
|
||||
/**
|
||||
* verify channel meta data
|
||||
*/
|
||||
@Test
|
||||
public void metadata() throws Exception {
|
||||
|
||||
assertEquals(BufType.BYTE, new NioUdtByteConnectorChannel().metadata()
|
||||
.bufferType());
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.nio;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.buffer.BufType;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.transport.udt.util.BootHelp;
|
||||
import io.netty.transport.udt.util.EchoByteHandler;
|
||||
import io.netty.transport.udt.util.UnitHelp;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.yammer.metrics.Metrics;
|
||||
import com.yammer.metrics.core.Meter;
|
||||
|
||||
public class TestNioUdtByteRendezvousChannel extends TestAny {
|
||||
|
||||
/**
|
||||
* verify channel meta data
|
||||
*/
|
||||
@Test
|
||||
public void metadata() throws Exception {
|
||||
|
||||
assertEquals(BufType.BYTE, new NioUdtByteRendezvousChannel().metadata()
|
||||
.bufferType());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* verify basic echo byte rendezvous
|
||||
*/
|
||||
@Test(timeout = 10 * 1000)
|
||||
public void basicEcho() throws Exception {
|
||||
|
||||
final int messageSize = 64 * 1024;
|
||||
final int transferLimit = messageSize * 16;
|
||||
|
||||
final Meter rate1 = Metrics.newMeter(
|
||||
TestNioUdtMessageRendezvousChannel.class, "send rate", "bytes",
|
||||
TimeUnit.SECONDS);
|
||||
|
||||
final Meter rate2 = Metrics.newMeter(
|
||||
TestNioUdtMessageRendezvousChannel.class, "send rate", "bytes",
|
||||
TimeUnit.SECONDS);
|
||||
|
||||
final InetSocketAddress addr1 = UnitHelp.localSocketAddress();
|
||||
final InetSocketAddress addr2 = UnitHelp.localSocketAddress();
|
||||
|
||||
final EchoByteHandler handler1 = new EchoByteHandler(rate1, messageSize);
|
||||
final EchoByteHandler handler2 = new EchoByteHandler(rate2, messageSize);
|
||||
|
||||
final Bootstrap boot1 = BootHelp.bytePeerBoot(addr1, addr2, handler1);
|
||||
final Bootstrap boot2 = BootHelp.bytePeerBoot(addr2, addr1, handler2);
|
||||
|
||||
final ChannelFuture connectFuture1 = boot1.connect();
|
||||
final ChannelFuture connectFuture2 = boot2.connect();
|
||||
|
||||
while (handler1.meter().count() < transferLimit
|
||||
&& handler2.meter().count() < transferLimit) {
|
||||
|
||||
log.info("progress : {} {}", handler1.meter().count(), handler2
|
||||
.meter().count());
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
}
|
||||
|
||||
connectFuture1.channel().close().sync();
|
||||
connectFuture2.channel().close().sync();
|
||||
|
||||
log.info("handler1 : {}", handler1.meter().count());
|
||||
log.info("handler2 : {}", handler2.meter().count());
|
||||
|
||||
assertTrue(handler1.meter().count() >= transferLimit);
|
||||
assertTrue(handler2.meter().count() >= transferLimit);
|
||||
|
||||
assertEquals(handler1.meter().count(), handler2.meter().count());
|
||||
|
||||
boot1.shutdown();
|
||||
boot2.shutdown();
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.nio;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import io.netty.buffer.BufType;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestNioUdtMessageAcceptorChannel extends TestAny {
|
||||
|
||||
/**
|
||||
* verify channel meta data
|
||||
*/
|
||||
@Test
|
||||
public void metadata() throws Exception {
|
||||
|
||||
assertEquals(BufType.MESSAGE, new NioUdtMessageAcceptorChannel()
|
||||
.metadata().bufferType());
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.nio;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import io.netty.buffer.BufType;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestNioUdtMessageConnectorChannel extends TestAny {
|
||||
|
||||
/**
|
||||
* verify channel meta data
|
||||
*/
|
||||
@Test
|
||||
public void metadata() throws Exception {
|
||||
|
||||
assertEquals(BufType.MESSAGE, new NioUdtMessageConnectorChannel()
|
||||
.metadata().bufferType());
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.nio;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.buffer.BufType;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.transport.udt.util.BootHelp;
|
||||
import io.netty.transport.udt.util.EchoMessageHandler;
|
||||
import io.netty.transport.udt.util.UnitHelp;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.yammer.metrics.Metrics;
|
||||
import com.yammer.metrics.core.Meter;
|
||||
|
||||
public class TestNioUdtMessageRendezvousChannel extends TestAny {
|
||||
|
||||
/**
|
||||
* verify channel meta data
|
||||
*/
|
||||
@Test
|
||||
public void metadata() throws Exception {
|
||||
|
||||
assertEquals(BufType.MESSAGE, new NioUdtMessageRendezvousChannel()
|
||||
.metadata().bufferType());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* verify basic echo message rendezvous
|
||||
*/
|
||||
@Test(timeout = 10 * 1000)
|
||||
public void basicEcho() throws Exception {
|
||||
|
||||
final int messageSize = 64 * 1024;
|
||||
final int transferLimit = messageSize * 16;
|
||||
|
||||
final Meter rate1 = Metrics.newMeter(
|
||||
TestNioUdtMessageRendezvousChannel.class, "send rate", "bytes",
|
||||
TimeUnit.SECONDS);
|
||||
|
||||
final Meter rate2 = Metrics.newMeter(
|
||||
TestNioUdtMessageRendezvousChannel.class, "send rate", "bytes",
|
||||
TimeUnit.SECONDS);
|
||||
|
||||
final InetSocketAddress addr1 = UnitHelp.localSocketAddress();
|
||||
final InetSocketAddress addr2 = UnitHelp.localSocketAddress();
|
||||
|
||||
final EchoMessageHandler handler1 = new EchoMessageHandler(rate1,
|
||||
messageSize);
|
||||
final EchoMessageHandler handler2 = new EchoMessageHandler(rate2,
|
||||
messageSize);
|
||||
|
||||
final Bootstrap boot1 = BootHelp
|
||||
.messagePeerBoot(addr1, addr2, handler1);
|
||||
final Bootstrap boot2 = BootHelp
|
||||
.messagePeerBoot(addr2, addr1, handler2);
|
||||
|
||||
final ChannelFuture connectFuture1 = boot1.connect();
|
||||
final ChannelFuture connectFuture2 = boot2.connect();
|
||||
|
||||
while (handler1.meter().count() < transferLimit
|
||||
&& handler2.meter().count() < transferLimit) {
|
||||
|
||||
log.info("progress : {} {}", handler1.meter().count(), handler2
|
||||
.meter().count());
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
}
|
||||
|
||||
connectFuture1.channel().close().sync();
|
||||
connectFuture2.channel().close().sync();
|
||||
|
||||
log.info("handler1 : {}", handler1.meter().count());
|
||||
log.info("handler2 : {}", handler2.meter().count());
|
||||
|
||||
assertTrue(handler1.meter().count() >= transferLimit);
|
||||
assertTrue(handler2.meter().count() >= transferLimit);
|
||||
|
||||
assertEquals(handler1.meter().count(), handler2.meter().count());
|
||||
|
||||
boot1.shutdown();
|
||||
boot2.shutdown();
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.nio;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestNioUdtProvider extends TestAny {
|
||||
|
||||
/**
|
||||
* verify factory
|
||||
*/
|
||||
@Test
|
||||
public void provideFactory() {
|
||||
|
||||
// bytes
|
||||
assertNotNull(NioUdtProvider.BYTE_ACCEPTOR.newChannel());
|
||||
assertNotNull(NioUdtProvider.BYTE_CONNECTOR.newChannel());
|
||||
assertNotNull(NioUdtProvider.BYTE_RENDEZVOUS.newChannel());
|
||||
|
||||
// message
|
||||
assertNotNull(NioUdtProvider.MESSAGE_ACCEPTOR.newChannel());
|
||||
assertNotNull(NioUdtProvider.MESSAGE_CONNECTOR.newChannel());
|
||||
assertNotNull(NioUdtProvider.MESSAGE_RENDEZVOUS.newChannel());
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.util;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.socket.nio.NioEventLoopGroup;
|
||||
import io.netty.transport.udt.nio.NioUdtProvider;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
/**
|
||||
* Bootstrap utilities.
|
||||
*/
|
||||
public class BootHelp {
|
||||
|
||||
/**
|
||||
* bootstrap for byte rendezvous peer
|
||||
*/
|
||||
public static Bootstrap bytePeerBoot(final InetSocketAddress self,
|
||||
final InetSocketAddress peer, final ChannelHandler handler) {
|
||||
|
||||
final Bootstrap boot = new Bootstrap();
|
||||
|
||||
final ThreadFactory connectFactory = new UtilThreadFactory("peer");
|
||||
|
||||
final NioEventLoopGroup connectGroup = new NioEventLoopGroup(1,
|
||||
connectFactory, NioUdtProvider.BYTE_PROVIDER);
|
||||
|
||||
boot.group(connectGroup).channelFactory(NioUdtProvider.BYTE_RENDEZVOUS)
|
||||
.localAddress(self).remoteAddress(peer).handler(handler);
|
||||
|
||||
return boot;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* bootstrap for message rendezvous peer
|
||||
*/
|
||||
public static Bootstrap messagePeerBoot(final InetSocketAddress self,
|
||||
final InetSocketAddress peer, final ChannelHandler handler) {
|
||||
|
||||
final Bootstrap boot = new Bootstrap();
|
||||
|
||||
final ThreadFactory connectFactory = new UtilThreadFactory("peer");
|
||||
|
||||
final NioEventLoopGroup connectGroup = new NioEventLoopGroup(1,
|
||||
connectFactory, NioUdtProvider.MESSAGE_PROVIDER);
|
||||
|
||||
boot.group(connectGroup)
|
||||
.channelFactory(NioUdtProvider.MESSAGE_RENDEZVOUS)
|
||||
.localAddress(self).remoteAddress(peer).handler(handler);
|
||||
|
||||
return boot;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.util;
|
||||
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
import io.netty.logging.Slf4JLoggerFactory;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.caliper.SimpleBenchmark;
|
||||
|
||||
/**
|
||||
* Base class for caliper/metrics benchmarks.
|
||||
*/
|
||||
public abstract class CaliperBench extends SimpleBenchmark {
|
||||
|
||||
/**
|
||||
* Ensure no network latency after JVM shutdown
|
||||
*/
|
||||
static {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
TrafficControl.delay(0);
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Use slf4j logging.
|
||||
*/
|
||||
static {
|
||||
final InternalLoggerFactory defaultFactory = new Slf4JLoggerFactory();
|
||||
InternalLoggerFactory.setDefaultFactory(defaultFactory);
|
||||
}
|
||||
|
||||
protected final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private volatile CaliperMeasure measure;
|
||||
|
||||
/**
|
||||
* Caliper metrics wrapper.
|
||||
*/
|
||||
protected CaliperMeasure measure() {
|
||||
return measure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start measurement.
|
||||
*/
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
measure = new CaliperMeasure();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish measurement.
|
||||
*/
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
measure.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Measure time step and minimum run time.
|
||||
*/
|
||||
protected long markStep() {
|
||||
return 3 * 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Measure progress while in sleep.
|
||||
*/
|
||||
protected void markWait(final long time) throws Exception {
|
||||
|
||||
final long timeStart = System.currentTimeMillis();
|
||||
|
||||
while (true) {
|
||||
Thread.sleep(markStep());
|
||||
measure().mark();
|
||||
final long timeFinish = System.currentTimeMillis();
|
||||
if (timeFinish - timeStart >= time) {
|
||||
System.out.print("+\n");
|
||||
return;
|
||||
} else {
|
||||
System.out.print("-");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.caliper.Measurement;
|
||||
import com.google.caliper.MeasurementSet;
|
||||
import com.google.caliper.Run;
|
||||
import com.google.caliper.Scenario;
|
||||
import com.google.caliper.ScenarioResult;
|
||||
import com.yammer.metrics.core.Gauge;
|
||||
import com.yammer.metrics.core.Meter;
|
||||
import com.yammer.metrics.core.MetricsRegistry;
|
||||
import com.yammer.metrics.core.Timer;
|
||||
|
||||
/**
|
||||
* Caliper measure with Metrics provider.
|
||||
* <p>
|
||||
* measure up to 3 values: {@link #rate()}, {@link #time()}, {@link #size()}
|
||||
*/
|
||||
public class CaliperMeasure {
|
||||
|
||||
private final static Logger log = LoggerFactory
|
||||
.getLogger(CaliperMeasure.class);
|
||||
|
||||
/**
|
||||
* Gauge any double value
|
||||
*/
|
||||
public static class SizeGuage extends Gauge<Double> {
|
||||
|
||||
private volatile Double size = 0.0;
|
||||
|
||||
@Override
|
||||
public Double value() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void value(final double number) {
|
||||
this.size = number;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default rate measurement units.
|
||||
*/
|
||||
private static final Map<String, Integer> RATE_UNIT = new HashMap<String, Integer>();
|
||||
static {
|
||||
RATE_UNIT.put("Rate B/s", 1);
|
||||
RATE_UNIT.put("Rate KB/s", 1024);
|
||||
RATE_UNIT.put("Rate MB/s", 1024 * 1024);
|
||||
RATE_UNIT.put("Rate GB/s", 1024 * 1024 * 1024);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default time measurement units.
|
||||
*/
|
||||
private static final Map<String, Integer> TIME_UNIT = new HashMap<String, Integer>();
|
||||
static {
|
||||
TIME_UNIT.put("Time ns", 1);
|
||||
TIME_UNIT.put("Time us", 1000);
|
||||
TIME_UNIT.put("Time ms", 1000 * 1000);
|
||||
TIME_UNIT.put("Time s ", 1000 * 1000 * 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default size measurement units.
|
||||
*/
|
||||
private static final Map<String, Integer> SIZE_UNIT = new HashMap<String, Integer>();
|
||||
static {
|
||||
SIZE_UNIT.put("Size B", 1);
|
||||
SIZE_UNIT.put("Size KB", 1024);
|
||||
SIZE_UNIT.put("Size MB", 1024 * 1024);
|
||||
SIZE_UNIT.put("Size GB", 1024 * 1024 * 1024);
|
||||
}
|
||||
|
||||
private final Map<Long, Measurement> rateMap = new HashMap<Long, Measurement>();
|
||||
private final Map<Long, Measurement> timeMap = new HashMap<Long, Measurement>();
|
||||
private final Map<Long, Measurement> sizeMap = new HashMap<Long, Measurement>();
|
||||
|
||||
private final MetricsRegistry metrics = new MetricsRegistry();
|
||||
|
||||
private final Meter rate = metrics.newMeter(getClass(), "rate", "bytes",
|
||||
TimeUnit.SECONDS);
|
||||
|
||||
private final Timer time = metrics.newTimer(getClass(), "time",
|
||||
TimeUnit.NANOSECONDS, TimeUnit.SECONDS);
|
||||
|
||||
private final SizeGuage size = new SizeGuage();
|
||||
{
|
||||
metrics.newGauge(getClass(), "", size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rate meter.
|
||||
*/
|
||||
public Meter rate() {
|
||||
return rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time meter.
|
||||
*/
|
||||
public Timer time() {
|
||||
return time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Size meter.
|
||||
*/
|
||||
public SizeGuage size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Workaround: zero breaks gwt web app.
|
||||
*/
|
||||
private double filter(final double value) {
|
||||
if (value <= 0.0) {
|
||||
return 1.0;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform measurement; convert from metrics into caliper.
|
||||
*/
|
||||
public void mark() {
|
||||
final double rateValue = filter(rate.oneMinuteRate());
|
||||
final double timeValue = filter(time.mean());
|
||||
final double sizeValue = filter(size.value());
|
||||
if (rateValue == 1.0 && timeValue == 1.0 && sizeValue == 1.0) {
|
||||
/** ignore complete blank entries */
|
||||
return;
|
||||
}
|
||||
{
|
||||
final Measurement mark = new Measurement(RATE_UNIT, rateValue,
|
||||
rateValue);
|
||||
rateMap.put(System.nanoTime(), mark);
|
||||
}
|
||||
{
|
||||
final Measurement mark = new Measurement(TIME_UNIT, timeValue,
|
||||
timeValue);
|
||||
timeMap.put(System.nanoTime(), mark);
|
||||
}
|
||||
{
|
||||
final Measurement mark = new Measurement(SIZE_UNIT, sizeValue,
|
||||
sizeValue);
|
||||
sizeMap.put(System.nanoTime(), mark);
|
||||
}
|
||||
}
|
||||
|
||||
private final Map<String, String> variables = new HashMap<String, String>();
|
||||
|
||||
/**
|
||||
* Caliper scenario variables.
|
||||
*/
|
||||
public Map<String, String> variables() {
|
||||
return variables;
|
||||
}
|
||||
|
||||
private MeasurementSet measurementSet(final Map<Long, Measurement> map) {
|
||||
final Measurement[] array = map.values().toArray(new Measurement[0]);
|
||||
final MeasurementSet set = new MeasurementSet(array);
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach this measure to parent caliper run.
|
||||
*/
|
||||
public void appendTo(final Run run) {
|
||||
|
||||
final Scenario scenario = new Scenario(variables());
|
||||
|
||||
/** display rate as caliper durations */
|
||||
final MeasurementSet timeSet = measurementSet(rateMap);
|
||||
final String timeLog = null;
|
||||
|
||||
/** display time as caliper instances */
|
||||
final MeasurementSet instSet = measurementSet(timeMap);
|
||||
final String instLog = null;
|
||||
|
||||
/** display size as caliper memory */
|
||||
final MeasurementSet heapSet = measurementSet(sizeMap);
|
||||
final String heapLog = null;
|
||||
|
||||
final ScenarioResult scenarioResult = new ScenarioResult(timeSet,
|
||||
timeLog, instSet, instLog, heapSet, heapLog);
|
||||
|
||||
final Map<Scenario, ScenarioResult> measurements = run
|
||||
.getMeasurements();
|
||||
|
||||
measurements.put(scenario, scenarioResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminate metrics resources.
|
||||
*/
|
||||
public void shutdown() {
|
||||
rate.stop();
|
||||
time.stop();
|
||||
metrics.shutdown();
|
||||
}
|
||||
}
|
@ -0,0 +1,245 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.util;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.caliper.ConfiguredBenchmark;
|
||||
import com.google.caliper.Environment;
|
||||
import com.google.caliper.EnvironmentGetter;
|
||||
import com.google.caliper.Json;
|
||||
import com.google.caliper.Result;
|
||||
import com.google.caliper.Run;
|
||||
import com.google.caliper.Runner;
|
||||
import com.google.caliper.Scenario;
|
||||
import com.google.caliper.ScenarioResult;
|
||||
import com.google.caliper.SimpleBenchmark;
|
||||
import com.yammer.metrics.core.TimerContext;
|
||||
|
||||
/**
|
||||
* Custom caliper runner for {@link CaliperBench}.
|
||||
*/
|
||||
public final class CaliperRunner {
|
||||
|
||||
private final static Logger log = LoggerFactory
|
||||
.getLogger(CaliperRunner.class);
|
||||
|
||||
private CaliperRunner() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse bench parameters.
|
||||
*/
|
||||
public static List<String> valueList(final String valueText) {
|
||||
return Arrays.asList(valueText.split(","));
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute full cycle: warm up, execute and publish benchmark.
|
||||
*/
|
||||
public static void execute(final Class<? extends CaliperBench> klaz)
|
||||
throws Exception {
|
||||
Run run;
|
||||
run = execute("WARMUP", klaz);
|
||||
run = execute("REPORT", klaz);
|
||||
publish(newResult(run));
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute benchmark for all parameter combinations.
|
||||
*/
|
||||
public static Run execute(final String name,
|
||||
final Class<? extends CaliperBench> klaz) throws Exception {
|
||||
|
||||
final CaliperBench booter = klaz.newInstance();
|
||||
|
||||
final List<Map<String, String>> varsSet = product(booter);
|
||||
|
||||
final Run run = newRun(klaz.getName());
|
||||
|
||||
int index = 0;
|
||||
for (final Map<String, String> vars : varsSet) {
|
||||
final int done = 100 * index++ / varsSet.size();
|
||||
|
||||
log.info("{} {}% {}", name, done, vars);
|
||||
|
||||
/** call setUp() */
|
||||
final ConfiguredBenchmark runner = booter.createBenchmark(vars);
|
||||
|
||||
final CaliperBench bench = (CaliperBench) runner.getBenchmark();
|
||||
final CaliperMeasure measure = bench.measure();
|
||||
measure.variables().putAll(vars);
|
||||
|
||||
/** call timeXXX() */
|
||||
runner.run(0);
|
||||
|
||||
/** call tearDown() */
|
||||
runner.close();
|
||||
|
||||
measure.appendTo(run);
|
||||
}
|
||||
|
||||
return run;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert caliper result into JSON string.
|
||||
*/
|
||||
public static String json(final Result result) {
|
||||
return Json.getGsonInstance().toJson(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map signature based on map values.
|
||||
*/
|
||||
public static String signature(final Map<String, String> map) {
|
||||
final StringBuilder text = new StringBuilder();
|
||||
for (final String item : map.values()) {
|
||||
text.append(String.format("%20s", item));
|
||||
}
|
||||
return text.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate all parameter combinations for {@link SimpleBenchmark}.
|
||||
*/
|
||||
public static List<Map<String, String>> product(final SimpleBenchmark bench) {
|
||||
final Set<Map<String, String>> collect = new HashSet<Map<String, String>>();
|
||||
final Map<String, Set<String>> pending = new TreeMap<String, Set<String>>();
|
||||
for (final String name : new TreeSet<String>(bench.parameterNames())) {
|
||||
pending.put(name, bench.parameterValues(name));
|
||||
}
|
||||
final List<Map<String, String>> list = new ArrayList<Map<String, String>>(
|
||||
product(collect, pending));
|
||||
final Comparator<Map<String, String>> comp = new Comparator<Map<String, String>>() {
|
||||
@Override
|
||||
public int compare(final Map<String, String> o1,
|
||||
final Map<String, String> o2) {
|
||||
return signature(o1).compareTo(signature(o2));
|
||||
}
|
||||
};
|
||||
Collections.sort(list, comp);
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate ordered Cartesian product of sets.
|
||||
*/
|
||||
public static Set<Map<String, String>> product(
|
||||
final Set<Map<String, String>> collect,
|
||||
final Map<String, Set<String>> pending) {
|
||||
|
||||
if (pending.isEmpty()) {
|
||||
return collect;
|
||||
}
|
||||
|
||||
final Set<Map<String, String>> extract = new HashSet<Map<String, String>>();
|
||||
final String key = pending.keySet().iterator().next();
|
||||
for (final String value : pending.remove(key)) {
|
||||
final Map<String, String> map = new TreeMap<String, String>();
|
||||
map.put(key, value);
|
||||
extract.add(map);
|
||||
}
|
||||
|
||||
if (collect.isEmpty()) {
|
||||
collect.addAll(extract);
|
||||
return product(collect, pending);
|
||||
} else {
|
||||
final Set<Map<String, String>> inject = new HashSet<Map<String, String>>();
|
||||
for (final Map<String, String> mapExtr : extract) {
|
||||
for (final Map<String, String> mapColl : collect) {
|
||||
final Map<String, String> mapProd = new TreeMap<String, String>();
|
||||
mapProd.putAll(mapExtr);
|
||||
mapProd.putAll(mapColl);
|
||||
inject.add(mapProd);
|
||||
}
|
||||
}
|
||||
return product(inject, pending);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish result on http://microbenchmarks.appspot.com
|
||||
*/
|
||||
public static void publish(final Result result) throws Exception {
|
||||
final Runner runner = new Runner();
|
||||
final Method method = runner.getClass().getDeclaredMethod(
|
||||
"postResults", Result.class);
|
||||
method.setAccessible(true);
|
||||
method.invoke(runner, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide new named run instance.
|
||||
*/
|
||||
public static Run newRun(final String benchmarkName) {
|
||||
final Map<Scenario, ScenarioResult> measurements = new HashMap<Scenario, ScenarioResult>();
|
||||
final Date executedTimestamp = new Date();
|
||||
final Run run = new Run(measurements, benchmarkName, executedTimestamp);
|
||||
return run;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make new result from run.
|
||||
*/
|
||||
public static Result newResult(final Run run) {
|
||||
final Environment env = new EnvironmentGetter()
|
||||
.getEnvironmentSnapshot();
|
||||
final Result result = new Result(run, env);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify measure publication manually.
|
||||
*/
|
||||
public static void main(final String[] args) throws Exception {
|
||||
final Run run = newRun("test-main");
|
||||
for (int param = 0; param < 5; param++) {
|
||||
final CaliperMeasure measure = new CaliperMeasure();
|
||||
measure.variables().put("param", "" + param);
|
||||
for (int step = 0; step < 5; step++) {
|
||||
measure.rate().mark(50 + step);
|
||||
final TimerContext time = measure.time().time();
|
||||
Thread.sleep(15);
|
||||
time.stop();
|
||||
measure.size().value(50 + step);
|
||||
measure.mark();
|
||||
}
|
||||
measure.appendTo(run);
|
||||
}
|
||||
final Result result = newResult(run);
|
||||
publish(result);
|
||||
System.out.println(json(result));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.util;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.yammer.metrics.Metrics;
|
||||
import com.yammer.metrics.core.Clock;
|
||||
import com.yammer.metrics.core.Counter;
|
||||
import com.yammer.metrics.core.Gauge;
|
||||
import com.yammer.metrics.core.Histogram;
|
||||
import com.yammer.metrics.core.Metered;
|
||||
import com.yammer.metrics.core.Metric;
|
||||
import com.yammer.metrics.core.MetricName;
|
||||
import com.yammer.metrics.core.MetricPredicate;
|
||||
import com.yammer.metrics.core.MetricProcessor;
|
||||
import com.yammer.metrics.core.MetricsRegistry;
|
||||
import com.yammer.metrics.core.Timer;
|
||||
import com.yammer.metrics.reporting.AbstractPollingReporter;
|
||||
import com.yammer.metrics.stats.Snapshot;
|
||||
|
||||
/**
|
||||
* A simple reporters which prints out application metrics to a
|
||||
* {@link PrintStream} periodically.
|
||||
*/
|
||||
public class CustomReporter extends AbstractPollingReporter implements
|
||||
MetricProcessor<PrintStream> {
|
||||
private static final int CONSOLE_WIDTH = 80;
|
||||
|
||||
/**
|
||||
* Enables the console reporter for the default metrics registry, and causes
|
||||
* it to print to STDOUT with the specified period.
|
||||
*/
|
||||
public static void enable(final long period, final TimeUnit unit) {
|
||||
enable(Metrics.defaultRegistry(), period, unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the console reporter for the given metrics registry, and causes
|
||||
* it to print to STDOUT with the specified period and unrestricted output.
|
||||
*/
|
||||
public static void enable(final MetricsRegistry metricsRegistry,
|
||||
final long period, final TimeUnit unit) {
|
||||
final CustomReporter reporter = new CustomReporter(
|
||||
metricsRegistry, System.out, MetricPredicate.ALL);
|
||||
reporter.start(period, unit);
|
||||
}
|
||||
|
||||
private final PrintStream out;
|
||||
private final MetricPredicate predicate;
|
||||
private final Clock clock;
|
||||
private final TimeZone timeZone;
|
||||
private final Locale locale;
|
||||
|
||||
/**
|
||||
* Creates a new {@link CustomReporter} for the default metrics
|
||||
* registry, with unrestricted output.
|
||||
*/
|
||||
public CustomReporter(final PrintStream out) {
|
||||
this(Metrics.defaultRegistry(), out, MetricPredicate.ALL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link CustomReporter} for a given metrics registry.
|
||||
*/
|
||||
public CustomReporter(final MetricsRegistry metricsRegistry,
|
||||
final PrintStream out, final MetricPredicate predicate) {
|
||||
this(metricsRegistry, out, predicate, Clock.defaultClock(), TimeZone
|
||||
.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link CustomReporter} for a given metrics registry.
|
||||
*/
|
||||
public CustomReporter(final MetricsRegistry metricsRegistry,
|
||||
final PrintStream out, final MetricPredicate predicate,
|
||||
final Clock clock, final TimeZone timeZone) {
|
||||
this(metricsRegistry, out, predicate, clock, timeZone, Locale
|
||||
.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link CustomReporter} for a given metrics registry.
|
||||
*/
|
||||
public CustomReporter(final MetricsRegistry metricsRegistry,
|
||||
final PrintStream out, final MetricPredicate predicate,
|
||||
final Clock clock, final TimeZone timeZone, final Locale locale) {
|
||||
super(metricsRegistry, "console-reporter");
|
||||
this.out = out;
|
||||
this.predicate = predicate;
|
||||
this.clock = clock;
|
||||
this.timeZone = timeZone;
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final DateFormat format = DateFormat.getDateTimeInstance(
|
||||
DateFormat.SHORT, DateFormat.MEDIUM, locale);
|
||||
format.setTimeZone(timeZone);
|
||||
final String dateTime = format.format(new Date(clock.time()));
|
||||
out.print(dateTime);
|
||||
out.print(' ');
|
||||
for (int i = 0; i < (CONSOLE_WIDTH - dateTime.length() - 1); i++) {
|
||||
out.print('=');
|
||||
}
|
||||
out.println();
|
||||
for (final Entry<String, SortedMap<MetricName, Metric>> entry : getMetricsRegistry()
|
||||
.groupedMetrics(predicate).entrySet()) {
|
||||
out.print(entry.getKey());
|
||||
out.println(':');
|
||||
for (final Entry<MetricName, Metric> subEntry : entry
|
||||
.getValue().entrySet()) {
|
||||
out.print(" ");
|
||||
out.print(subEntry.getKey().getName());
|
||||
out.println(':');
|
||||
subEntry.getValue().processWith(this, subEntry.getKey(),
|
||||
out);
|
||||
out.println();
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
out.println();
|
||||
out.flush();
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace(out);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processGauge(final MetricName name, final Gauge<?> gauge,
|
||||
final PrintStream stream) {
|
||||
stream.printf(locale, " value = %s\n", gauge.value());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCounter(final MetricName name, final Counter counter,
|
||||
final PrintStream stream) {
|
||||
stream.printf(locale, " count = %,d\n", counter.count());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processMeter(final MetricName name, final Metered meter,
|
||||
final PrintStream stream) {
|
||||
final String unit = abbrev(meter.rateUnit());
|
||||
stream.printf(locale, " count = %,d\n", meter.count());
|
||||
stream.printf(locale, " mean rate = %,2.2f %s/%s\n",
|
||||
meter.meanRate(), meter.eventType(), unit);
|
||||
stream.printf(locale, " 1-minute rate = %,2.2f %s/%s\n",
|
||||
meter.oneMinuteRate(), meter.eventType(), unit);
|
||||
stream.printf(locale, " 5-minute rate = %,2.2f %s/%s\n",
|
||||
meter.fiveMinuteRate(), meter.eventType(), unit);
|
||||
stream.printf(locale, " 15-minute rate = %,2.2f %s/%s\n",
|
||||
meter.fifteenMinuteRate(), meter.eventType(), unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processHistogram(final MetricName name,
|
||||
final Histogram histogram, final PrintStream stream) {
|
||||
final Snapshot snapshot = histogram.getSnapshot();
|
||||
stream.printf(locale, " min = %,2.2f\n", histogram.min());
|
||||
stream.printf(locale, " max = %,2.2f\n", histogram.max());
|
||||
stream.printf(locale, " mean = %,2.2f\n", histogram.mean());
|
||||
stream.printf(locale, " stddev = %,2.2f\n",
|
||||
histogram.stdDev());
|
||||
stream.printf(locale, " median = %,2.2f\n",
|
||||
snapshot.getMedian());
|
||||
stream.printf(locale, " 75%% <= %,2.2f\n",
|
||||
snapshot.get75thPercentile());
|
||||
stream.printf(locale, " 95%% <= %,2.2f\n",
|
||||
snapshot.get95thPercentile());
|
||||
stream.printf(locale, " 98%% <= %,2.2f\n",
|
||||
snapshot.get98thPercentile());
|
||||
stream.printf(locale, " 99%% <= %,2.2f\n",
|
||||
snapshot.get99thPercentile());
|
||||
stream.printf(locale, " 99.9%% <= %,2.2f\n",
|
||||
snapshot.get999thPercentile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processTimer(final MetricName name, final Timer timer,
|
||||
final PrintStream stream) {
|
||||
processMeter(name, timer, stream);
|
||||
final String durationUnit = abbrev(timer.durationUnit());
|
||||
final Snapshot snapshot = timer.getSnapshot();
|
||||
stream.printf(locale, " min = %,2.2f %s\n", timer.min(),
|
||||
durationUnit);
|
||||
stream.printf(locale, " max = %,2.2f %s\n", timer.max(),
|
||||
durationUnit);
|
||||
stream.printf(locale, " mean = %,2.2f %s\n", timer.mean(),
|
||||
durationUnit);
|
||||
stream.printf(locale, " stddev = %,2.2f %s\n",
|
||||
timer.stdDev(), durationUnit);
|
||||
stream.printf(locale, " median = %,2.2f %s\n",
|
||||
snapshot.getMedian(), durationUnit);
|
||||
stream.printf(locale, " 75%% <= %,2.2f %s\n",
|
||||
snapshot.get75thPercentile(), durationUnit);
|
||||
stream.printf(locale, " 95%% <= %,2.2f %s\n",
|
||||
snapshot.get95thPercentile(), durationUnit);
|
||||
stream.printf(locale, " 98%% <= %,2.2f %s\n",
|
||||
snapshot.get98thPercentile(), durationUnit);
|
||||
stream.printf(locale, " 99%% <= %,2.2f %s\n",
|
||||
snapshot.get99thPercentile(), durationUnit);
|
||||
stream.printf(locale, " 99.9%% <= %,2.2f %s\n",
|
||||
snapshot.get999thPercentile(), durationUnit);
|
||||
}
|
||||
|
||||
private String abbrev(final TimeUnit unit) {
|
||||
switch (unit) {
|
||||
case NANOSECONDS:
|
||||
return "ns";
|
||||
case MICROSECONDS:
|
||||
return "us";
|
||||
case MILLISECONDS:
|
||||
return "ms";
|
||||
case SECONDS:
|
||||
return "s";
|
||||
case MINUTES:
|
||||
return "m";
|
||||
case HOURS:
|
||||
return "h";
|
||||
case DAYS:
|
||||
return "d";
|
||||
default:
|
||||
throw new IllegalArgumentException("Unrecognized TimeUnit: " + unit);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.util;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundByteHandlerAdapter;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.transport.udt.nio.NioUdtProvider;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.yammer.metrics.core.Meter;
|
||||
|
||||
/**
|
||||
* Handler implementation for the echo client. It initiates the ping-pong
|
||||
* traffic between the echo client and server by sending the first message to
|
||||
* the server on activation.
|
||||
*/
|
||||
public class EchoByteHandler extends ChannelInboundByteHandlerAdapter {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(EchoByteHandler.class.getName());
|
||||
|
||||
private final ByteBuf message;
|
||||
|
||||
private final Meter meter;
|
||||
|
||||
public Meter meter() {
|
||||
return meter;
|
||||
}
|
||||
|
||||
public EchoByteHandler(final Meter meter, final int messageSize) {
|
||||
|
||||
this.meter = meter;
|
||||
|
||||
message = Unpooled.buffer(messageSize);
|
||||
|
||||
for (int i = 0; i < message.capacity(); i++) {
|
||||
message.writeByte((byte) i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(final ChannelHandlerContext ctx) throws Exception {
|
||||
|
||||
log.info("ECHO active {}", NioUdtProvider.socketUDT(ctx.channel())
|
||||
.toStringOptions());
|
||||
|
||||
ctx.write(message);
|
||||
|
||||
ctx.flush();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inboundBufferUpdated(final ChannelHandlerContext ctx,
|
||||
final ByteBuf in) {
|
||||
|
||||
if (meter != null) {
|
||||
meter.mark(in.readableBytes());
|
||||
}
|
||||
|
||||
final ByteBuf out = ctx.nextOutboundByteBuffer();
|
||||
|
||||
out.discardReadBytes(); // FIXME
|
||||
|
||||
out.writeBytes(in);
|
||||
|
||||
ctx.flush();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(final ChannelHandlerContext ctx,
|
||||
final Throwable e) {
|
||||
|
||||
log.error("exception : {}", e.getMessage());
|
||||
|
||||
ctx.close();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf newInboundBuffer(final ChannelHandlerContext ctx)
|
||||
throws Exception {
|
||||
|
||||
return ctx.alloc().directBuffer(
|
||||
ctx.channel().config().getOption(ChannelOption.SO_RCVBUF));
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.util;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.MessageBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundMessageHandlerAdapter;
|
||||
import io.netty.transport.udt.UdtMessage;
|
||||
import io.netty.transport.udt.nio.NioUdtProvider;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.yammer.metrics.core.Meter;
|
||||
|
||||
/**
|
||||
* Handler implementation for the echo peer. It initiates the ping-pong traffic
|
||||
* between the echo peers by sending the first message to the other peer on
|
||||
* activation.
|
||||
*/
|
||||
public class EchoMessageHandler extends
|
||||
ChannelInboundMessageHandlerAdapter<UdtMessage> {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(EchoMessageHandler.class.getName());
|
||||
|
||||
private final Meter meter;
|
||||
private final UdtMessage message;
|
||||
|
||||
public Meter meter() {
|
||||
return meter;
|
||||
}
|
||||
|
||||
public EchoMessageHandler(final Meter meter, final int messageSize) {
|
||||
|
||||
super(UdtMessage.class);
|
||||
|
||||
this.meter = meter;
|
||||
|
||||
final ByteBuf byteBuf = Unpooled.buffer(messageSize);
|
||||
|
||||
for (int i = 0; i < byteBuf.capacity(); i++) {
|
||||
byteBuf.writeByte((byte) i);
|
||||
}
|
||||
|
||||
this.message = new UdtMessage(byteBuf);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(final ChannelHandlerContext ctx) throws Exception {
|
||||
|
||||
log.info("ECHO active {}", NioUdtProvider.socketUDT(ctx.channel())
|
||||
.toStringOptions());
|
||||
|
||||
final MessageBuf<Object> out = ctx.nextOutboundMessageBuffer();
|
||||
|
||||
out.add(message);
|
||||
|
||||
ctx.flush();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(final ChannelHandlerContext ctx,
|
||||
final Throwable e) {
|
||||
|
||||
log.error("exception : {}", e.getMessage());
|
||||
|
||||
ctx.close();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void messageReceived(final ChannelHandlerContext ctx,
|
||||
final UdtMessage message) throws Exception {
|
||||
|
||||
final ByteBuf byteBuf = message.data();
|
||||
|
||||
if (meter != null) {
|
||||
meter.mark(byteBuf.readableBytes());
|
||||
}
|
||||
|
||||
final MessageBuf<Object> out = ctx.nextOutboundMessageBuffer();
|
||||
|
||||
out.add(message);
|
||||
|
||||
ctx.flush();
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.util;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Introduce traffic control, such as transfer latency.
|
||||
* <p>
|
||||
* requires sudo setup for /sbin/tc under current account
|
||||
* <p>
|
||||
* see http://www.davidverhasselt.com/2008/01/27/passwordless-sudo/
|
||||
*/
|
||||
public final class TrafficControl {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(TrafficControl.class.getName());
|
||||
|
||||
private TrafficControl() {
|
||||
}
|
||||
|
||||
private static final String TC_DELAY = "sudo tc qdisc add dev %s root netem delay %sms limit %s";
|
||||
private static final String TC_RESET = "sudo tc qdisc del dev %s root";
|
||||
|
||||
/**
|
||||
* verify if traffic control is available
|
||||
*/
|
||||
public static boolean isAvailable() {
|
||||
try {
|
||||
final int millis = 100;
|
||||
final int margin = 20;
|
||||
delay(0);
|
||||
final long time1 = UnitHelp.ping("localhost");
|
||||
delay(millis);
|
||||
final long time2 = UnitHelp.ping("localhost");
|
||||
delay(0);
|
||||
final long time3 = UnitHelp.ping("localhost");
|
||||
return time2 >= time1 + millis - margin
|
||||
&& time2 >= time3 + millis - margin;
|
||||
} catch (final Throwable e) {
|
||||
log.debug("", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Introduce round-trip delay on local host
|
||||
* @param time - delay in milliseconds; use zero to remove delay.
|
||||
*/
|
||||
public static void delay(final int time) throws Exception {
|
||||
if (time < 0) {
|
||||
throw new IllegalArgumentException("negative latency");
|
||||
}
|
||||
final int delay = time / 2;
|
||||
if (delay == 0) {
|
||||
UnitHelp.process(String.format(TC_RESET, "lo"));
|
||||
} else {
|
||||
/** extend packet buffer queue to avoid packet loss due to latency */
|
||||
final int limit = 1024 * 1024;
|
||||
UnitHelp.process(String.format(TC_RESET, "lo"));
|
||||
UnitHelp.process(String.format(TC_DELAY, "lo", delay, limit));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.HashSet;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.barchart.udt.SocketUDT;
|
||||
import com.barchart.udt.StatusUDT;
|
||||
|
||||
/**
|
||||
* Unit test helper.
|
||||
*/
|
||||
public final class UnitHelp {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(UnitHelp.class);
|
||||
|
||||
/**
|
||||
* Zero out buffer.
|
||||
*/
|
||||
public static void clear(final IntBuffer buffer) {
|
||||
for (int index = 0; index < buffer.capacity(); index++) {
|
||||
buffer.put(index, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Measure ping time to a host.
|
||||
*/
|
||||
public static long ping(final String host) throws Exception {
|
||||
final String name = System.getProperty("os.name").toLowerCase();
|
||||
|
||||
final String command;
|
||||
if (name.contains("linux")) {
|
||||
command = "ping -c 1 " + host;
|
||||
} else if (name.contains("mac os x")) {
|
||||
command = "ping -c 1 " + host;
|
||||
} else if (name.contains("windows")) {
|
||||
command = "ping -n 1 " + host;
|
||||
} else {
|
||||
throw new Exception("unknown platform");
|
||||
}
|
||||
|
||||
final long timeStart = System.currentTimeMillis();
|
||||
|
||||
process(command);
|
||||
|
||||
final long timeFinish = System.currentTimeMillis();
|
||||
|
||||
final long timeDiff = timeFinish - timeStart;
|
||||
|
||||
return timeDiff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke external process and wait for completion.
|
||||
*/
|
||||
public static void process(final String command) throws Exception {
|
||||
final ProcessBuilder builder = new ProcessBuilder(command.split("\\s+"));
|
||||
final Process process = builder.start();
|
||||
process.waitFor();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return newly allocated address or null for failure
|
||||
*/
|
||||
public static synchronized InetSocketAddress findLocalAddress(
|
||||
final String host) {
|
||||
ServerSocket socket = null;
|
||||
try {
|
||||
final InetAddress address = InetAddress.getByName(host);
|
||||
socket = new ServerSocket(0, 3, address);
|
||||
return (InetSocketAddress) socket.getLocalSocketAddress();
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to find addess.");
|
||||
return null;
|
||||
} finally {
|
||||
if (socket != null) {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to close socket.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find named address on local host.
|
||||
*/
|
||||
public static InetSocketAddress hostedSocketAddress(final String host)
|
||||
throws Exception {
|
||||
for (int k = 0; k < 10; k++) {
|
||||
final InetSocketAddress address = findLocalAddress(host);
|
||||
if (address == null) {
|
||||
Thread.sleep(500);
|
||||
continue;
|
||||
}
|
||||
return address;
|
||||
}
|
||||
throw new Exception("Failed to allocate address.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate available local address / port or throw exception.
|
||||
*/
|
||||
public static InetSocketAddress localSocketAddress() throws Exception {
|
||||
return hostedSocketAddress("localhost");
|
||||
}
|
||||
|
||||
/**
|
||||
* Display contents of a buffer.
|
||||
*/
|
||||
public static void logBuffer(final String title, final IntBuffer buffer) {
|
||||
for (int index = 0; index < buffer.capacity(); index++) {
|
||||
final int value = buffer.get(index);
|
||||
if (value == 0) {
|
||||
continue;
|
||||
}
|
||||
log.info(String.format("%s [id: 0x%08x]", title, value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display java.class.path
|
||||
*/
|
||||
public static void logClassPath() {
|
||||
final String classPath = System.getProperty("java.class.path");
|
||||
final String[] entries = classPath.split(File.pathSeparator);
|
||||
final StringBuilder text = new StringBuilder(1024);
|
||||
for (final String item : entries) {
|
||||
text.append("\n\t");
|
||||
text.append(item);
|
||||
}
|
||||
log.info("\n\t[java.class.path]{}", text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display java.library.path
|
||||
*/
|
||||
public static void logLibraryPath() {
|
||||
final String classPath = System.getProperty("java.library.path");
|
||||
final String[] entries = classPath.split(File.pathSeparator);
|
||||
final StringBuilder text = new StringBuilder(1024);
|
||||
for (final String item : entries) {
|
||||
text.append("\n\t");
|
||||
text.append(item);
|
||||
}
|
||||
log.info("\n\t[java.library.path]{}", text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display current OS/ARCH.
|
||||
*/
|
||||
public static void logOsArch() {
|
||||
final StringBuilder text = new StringBuilder(1024);
|
||||
text.append("\n\t");
|
||||
text.append(System.getProperty("os.name"));
|
||||
text.append("\n\t");
|
||||
text.append(System.getProperty("os.arch"));
|
||||
log.info("\n\t[os/arch]{}", text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display contents of a set.
|
||||
*/
|
||||
public static void logSet(final Set<?> set) {
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
final TreeSet<?> treeSet = new TreeSet(set);
|
||||
for (final Object item : treeSet) {
|
||||
log.info("-> {}", item);
|
||||
}
|
||||
}
|
||||
|
||||
public static String property(final String name) {
|
||||
final String value = System.getProperty(name);
|
||||
if (value == null) {
|
||||
log.error("property '{}' not defined; terminating", name);
|
||||
System.exit(1);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int[] randomIntArray(final int length, final int range) {
|
||||
final int[] array = new int[length];
|
||||
final Random generator = new Random(0);
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
array[i] = generator.nextInt(range);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public static String randomString() {
|
||||
return "" + System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public static String randomSuffix(final String name) {
|
||||
return name + "-" + System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Block till socket reaches given state.
|
||||
*/
|
||||
public static void socketAwait(final SocketUDT socket,
|
||||
final StatusUDT... statusArray) throws Exception {
|
||||
while (true) {
|
||||
for (final StatusUDT status : statusArray) {
|
||||
if (socket.status() == status) {
|
||||
return;
|
||||
} else {
|
||||
Thread.sleep(50);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<Integer> socketIndexSet(final IntBuffer buffer) {
|
||||
final Set<Integer> set = new HashSet<Integer>();
|
||||
while (buffer.hasRemaining()) {
|
||||
set.add(buffer.get());
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public static boolean socketPresent(final SocketUDT socket,
|
||||
final IntBuffer buffer) {
|
||||
for (int index = 0; index < buffer.capacity(); index++) {
|
||||
if (buffer.get(index) == socket.id()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private UnitHelp() {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.transport.udt.util;
|
||||
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Thread factory for tests.
|
||||
*/
|
||||
public class UtilThreadFactory implements ThreadFactory {
|
||||
|
||||
private static final AtomicInteger counter = new AtomicInteger();
|
||||
|
||||
private final String name;
|
||||
|
||||
public UtilThreadFactory(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Thread newThread(final Runnable runnable) {
|
||||
return new Thread(runnable, name + "-" + counter.getAndIncrement());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* UDT Benchmarks and Tests Utilities
|
||||
*/
|
||||
package io.netty.transport.udt.util;
|
||||
|
16
transport-udt/src/test/resources/logback-test.xml
Normal file
16
transport-udt/src/test/resources/logback-test.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<configuration debug="false">
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%date{ss.SSS} [%5.5thread] %-5level %16.16class{16} %-16.16method{16} %3.3line - %message%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="debug">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
<logger name="com.barchart.udt.EpollUDT" level="INFO" />
|
||||
|
||||
</configuration>
|
Loading…
Reference in New Issue
Block a user