Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keeping state in a Netty ChannelHandler

The netty documentation suggest using instance variables in ChannelHandlers to keep track of channel state. It doesn't mention that you should use volatile variables or use any other synchronization technique to assure that there is a consistent view across threads.

For instance using this handler on a per-connection basis:

class Handler extends SimpleChannelUpstreamHandler {
        int count = 0;

        @Override
        public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
            ++count;
        }
}

I would expect that many different threads from a netty thread pool would be calling this method, although not concurrently, and could potentially see an inconsistent view, resulting in an inaccurate count.

Is this the case? or is there some kind of synchronization going on inside of netty that would cause the write to the count field to be flushed?

like image 362
S-C Avatar asked Nov 29 '11 00:11

S-C


2 Answers

If you do not have an executor in your pipeline, and are executing your handlers purely in the I/O worker threads, then you're fine as Netty guarantees that a given pipeline instance is always called back from the same worker thread.

If you're adding an execution handler to your pipeline then you are ok if you're using Netty's OrderedMemoryAwareThreadPoolExecutor.

If you are accessing your pipeline from a non-Netty thread, or you have a non-OrderedMemoryAwareThreadPoolExecutor in your pipeline then you need synchronisation.

I recommend taking a look through the following threads on the Netty user forum archives.

http://netty.markmail.org/search/?q=Memory+visibility+in+handlers#query:Memory%20visibility%20in%20handlers+page:1+mid:cmtw5omcxbg67sho+state:results

http://netty.markmail.org/search/?q=Periodic%20TimerTask%20in#query:Periodic%20TimerTask%20in+page:2+mid:vwahepiois4eqwkp+state:results

like image 197
johnstlr Avatar answered Nov 15 '22 19:11

johnstlr


When you create a Netty ChannelPipeline if you add the same instance of your Handler to all the channels then yes, multiple threads will read/modify your data.

If you create a new instance of Handler per channel in your pipeline as shown below then you are safe, only one thread will access the handler in the pipeline at a time then.

ChannelPipeline p = Channels.pipeline();
pipeline.addLast("handler", new Handler());

Also take a look at Netty ChannelLocal, its like java ThreadLocal and you can set the state on a per channel basis

like image 2
Abe Avatar answered Nov 15 '22 19:11

Abe