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?
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With