Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concurrency in Netty

I'm implementing ChannelInboundHandlerAdapter and have a question about concurrency. Is it necessary to make it thread safe? I mean I have to store some state for each client per their sessions.

public class Impl extends ChannelInboundHandlerAdapter{
    private List<Integer> someState;
    //

    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        int size = someState.size();  //Should I worry about memory consitency here?
        //...
    }
}

The thing is if from request to request the channelRead method is invoked by different threads I will have to put some memory barriers.

Is it necessary? Or Netty takes care of it by itself?

like image 849
St.Antario Avatar asked Oct 01 '17 01:10

St.Antario


1 Answers

For Netty 4.x

Well-defined thread model

There is no well-defined thread model in 3.x although there was an attempt to fix its inconsistency in 3.5. 4.0 defines a strict thread model that helps a user write a ChannelHandler without worrying too much about thread safety.

  • Netty will never call a ChannelHandler's methods concurrently, unless the ChannelHandler is annotated with @Sharable. This is regardless of the type of handler methods - inbound, outbound, or life cycle event handler methods.
    • A user does not need to synchronize either inbound or outbound event handler methods anymore.
    • 4.0 disallows adding a ChannelHandler more than once unless it's annotated with @Sharable.
  • There is always happens-before relationship between each ChannelHandler method invocations made by Netty.
    • A user does not need to define a volatile field to keep the state of a handler.
  • A user can specify an EventExecutor when he or she adds a handler to a ChannelPipeline.
    • If specified, the handler methods of the ChannelHandler are always invoked by the specified EventExecutor.
    • If unspecified, the handler methods are always invoked by the EventLoop that its associated Channel is registered to.
  • EventExecutor and EventLoop assigned to a handler or a channel are always single-threaded.
    • The handler methods will always be invoked by the same thread.
    • If multithreaded EventExecutor or EventLoop is specified, one of the threads will be chosen first and then the chosen thread will be used until deregistration.
    • If two handlers in the same pipeline are assigned with different EventExecutors, they are invoked simultaneously. A user has to pay attention to thread safety if more than one handler access shared data even if the shared data is accessed only by the handlers in the same pipeline.
  • The ChannelFutureListeners added to ChannelFuture are always invoked by the EventLoop thread assigned to the future's associated Channel.
  • ChannelHandlerInvoker can be used to control the ordering of Channel events. DefaultChannelHandlerInvoker immediately executes events from the EventLoop thread and executes events from other threads as Runnable objects on an EventExecutor. See the below example for implications this may have when interacting with a Channel from the EventLoop thread and other threads.

(emphasize is mine)

like image 109
Ruslan Stelmachenko Avatar answered Oct 20 '22 20:10

Ruslan Stelmachenko