Startup Sequence

Work in Progress

The article tries to shed light around how a MINA based application startup. For simplicity, we shall eliminate the Logging calls and shall consider a following sequence

Assumptions

  • The application is TCP based
  • Has one IOHandler for printing the incoming message
  • Has one XML Decoder, responsible for decoding incoming messages

About the Application

  • Listens for incoming connection on 8081 port
  • Received XML fragments, and combine them into complete XML
  • Prints the XML

Acceptor --> XML Decoder --> IOHandler

Following is the code around which we shall try to demystify the Startup Sequence

NioSocketAcceptor socketAcceptor = new NioSocketAcceptor();
// Add the XML Handler
socketAcceptor.setHandler(new XMLHandler());
		
SocketSessionConfig config = socketAcceptor.getSessionConfig();
config.setReuseAddress(true);
		
socketAcceptor.getFilterChain().addLast("logging", new LoggingFilter());
socketAcceptor.getFilterChain().addLast("xmlCodec", new ProtocolCodecFilter(new XMLCodecFactory()));
		
socketAcceptor.bind(new InetSocketAddress(8081));

Have used JIP (Java Interactive Profiler), for getting the detailed initialization sequence.
The complete initialization sequence shall be in multiple, part. First we shall take a detailed look at the core Acceptor and Processor initialization.

Let's get into the details

  1. We first create an NioAcceptor. Since we are using the default constructor, here is what happens. NioAcceptor is the class that handles incoming TCP/IP connections
  2. The default constructor creates an Instance of DefaultSocketSessionConfig class, and passes it to its parent class, along with the IoProcessor class, which in our case happens to be NioProcessor. We shall how the framework creates an instance of IoProcessor using reflection in while
  3. From Step# 2, the control goes to AbstractPollingIoAcceptor class. AbstractPollingIoAcceptor class is the base class that implements transport using polling strategy. It handles logic for bind, accept and dispose for ServerSocket. This is the place the Default Filter chain is also created.
  4. There is one important thing that is happening out here. It's the creation of a SimpleIoProcessorPool instance. It distributes the IoSession into one or more IoProcessors. The default size of the pool is "number of Processors(CPU) + 1". This is the place where the NioProcessor class is used (from Step# 2). Reflection is used to create an instance of NioProcessor. Since, we didn't supply Executor, a default cached Thread Pool executor is created
  5. Once all this is completed, the Selector is open and the polling System comes into action
  6. Now the IoAcceptor and IoProcessor's are ready

Now let's see how the components have come after this initialization sequence

Added by Ashish Paliwal, last edited by Emmanuel Lécharny on Jul 28, 2009  (view change)