user987654321
user987654321

Reputation: 52

Netty ThreadRenamingRunnable

I'm having a difficult time getting my head around how to use ThreadRenamingRunnable to rename the worker thread in netty. I am new to netty and using netty 3.9.0-Final.

I want to rename the worker threads..."New I/O worker #X". I'm ok with the name of the boss thread.

This is a basic server which responds to a "ping" with a "pong".

public class NettyPingPong {

    public static void main(String[] args) {
        ServerBootstrap bootstrap = new ServerBootstrap(
                new NioServerSocketChannelFactory(
                Executors.newCachedThreadPool(),
                Executors.newCachedThreadPool()));

        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
            public ChannelPipeline getPipeline() throws Exception {
                return Channels.pipeline(
                        new LineBasedFrameDecoder(255,true,true),
                        new PongUpstreamHandler(),
                        new StringEncoder());

            }
        });

        bootstrap.bind(new InetSocketAddress(8899));
            out.println("im ready");
        }
    }

and

public class PongUpstreamHandler extends SimpleChannelUpstreamHandler {

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {

        ChannelBuffer buffer = (ChannelBuffer) e.getMessage();
        String message = new String(buffer.array());
        if (message.equalsIgnoreCase("ping")){
            e.getChannel().write("pong\n");
            out.println("ponged...");
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
        e.getCause().printStackTrace();
        e.getChannel().close();
        out.println("closed...");
    }
}

Upvotes: 0

Views: 783

Answers (3)

Vaspar
Vaspar

Reputation: 576

1.5 years old question :( I landed here with the same question, working on Netty 3.5.0 Final. And I resolved with the below code.

I used a thread factory which would also generage meaningful threadNames similar to what Abe has mentioned. And, I configured ThreadRenamingRunnable not to rename the threads I supply. Using ThreadFactory and setting ThreadNameDeterminer as CURRENT.

ThreadRenamingRunnable.setThreadNameDeterminer(ThreadNameDeterminer.CURRENT);

Netty (3.5.0 atleast) alters the threadName from its original value to a proposed value "New I/O Worker #X". The above code snippet, ensures that it doesn't alter the thread name. The name is determined by the below ThreadFactory.

public class CustomThreadFactory implements ThreadFactory {
    private final AtomicInteger     threadIdSequence    = new AtomicInteger(0);
    private String                  threadNamePrefix    = "Netty-Worker-";

    public CustomThreadFactory() {
    }
    public CustomThreadFactory(String namePrefix) {
        this.threadNamePrefix = namePrefix;
    }

    @Override
    public Thread newThread(Runnable runnable) {
        Thread newThread = new Thread(runnable, threadNamePrefix + threadIdSequence.incrementAndGet());
        if (newThread.isDaemon()) {
            newThread.setDaemon(false);
        }
        if (newThread.getPriority() != Thread.NORM_PRIORITY) {
            newThread.setPriority(Thread.NORM_PRIORITY);
        }
        newThread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(final Thread thread, final Throwable e) {
                System.err.println(thread + " threw exception: " + e.getMessage());
                e.printStackTrace();
            }
        });
        return newThread;
    }
}

Upvotes: 1

Abe
Abe

Reputation: 9061

You can pass in a ThreadFactory which will name your thread. Take a look at this ThreadFactory I am using to name the server threads. Provided below is the example usage

serverBootstrap = new ServerBootstrap(
                            new NioServerSocketChannelFactory(Executors
                                .newCachedThreadPool(new NamedThreadFactory(
                                "TCP-Server-Boss")), Executors
                                .newCachedThreadPool(new NamedThreadFactory(
                                "TCP-Server-Worker"))));

Upvotes: 0

user987654321
user987654321

Reputation: 52

There may be better ways to do this, but this is how i got it to work. Thanks to this blog.

public class NettyPingPong {

    public static void main(String[] args) {

        final String WORKER_THREADNAME_PREFIX = "worker";
        NioWorkerPool workerPool = new NioWorkerPool(Executors.newCachedThreadPool(), 20, new ThreadNameDeterminer() {
            @Override
            public String determineThreadName(String currentThreadName,String proposedThreadName) throws Exception {
                StringBuilder sb = new StringBuilder(WORKER_THREADNAME_PREFIX);
                sb.append(currentThreadName.substring(currentThreadName.lastIndexOf('-')));
                return sb.toString();
            }
        });

        ServerBootstrap bootstrap = new ServerBootstrap(
                new NioServerSocketChannelFactory(
                Executors.newCachedThreadPool(),
                workerPool));

        bootstrap.setPipelineFactory(
                new ChannelPipelineFactory() {
            public ChannelPipeline getPipeline() throws Exception {
                return Channels.pipeline(
                        new LineBasedFrameDecoder(255, true, true),
                        new PongUpstreamHandler(),
                        new StringEncoder());

            }
        });

        bootstrap.bind(new InetSocketAddress(8899));
        out.println("im ready");
    }
}

Upvotes: 0

Related Questions