directory-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Marc Boorshtein" <mboorsht...@gmail.com>
Subject TCP service not shutting down cleanly
Date Tue, 26 Dec 2006 17:49:40 GMT
I hope everyone had a merry christmas and appoligies for sending this
to both lists, but I thought it was applicable to both apacheds and
mina.

I am utilizing the mina start and stop code from the apacheds class
"org.apache.directory.server.jndi.ServerContextFactory" in order to
start my own server.  The server starts OK, but when I try to stop the
server and start it again I am given the exception:

[2006-12-26 12:04:16,584][main] INFO  Server - Starting server...
[2006-12-26 12:04:16,909][main] ERROR Server - Could not bind to address
java.net.BindException: Address already in use
        at sun.nio.ch.Net.bind(Native Method)
        at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:119)
        at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:59)
        at org.apache.mina.transport.socket.nio.SocketAcceptor.registerNew(SocketAcceptor.java:442)
        at org.apache.mina.transport.socket.nio.SocketAcceptor.access$900(SocketAcceptor.java:52)
        at org.apache.mina.transport.socket.nio.SocketAcceptor$Worker.run(SocketAcceptor.java:268)
        at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)
        at java.lang.Thread.run(Thread.java:595)

Here is my startup code:

LdapProtocolProvider protocolProvider = new
LdapProtocolProvider(this.globalChain,this.router);
			
//			 Disable the disconnection of the clients on unbind
            SocketAcceptorConfig acceptorCfg = new SocketAcceptorConfig();
            acceptorCfg.setDisconnectOnUnbind( false );

            acceptorCfg.setReuseAddress( true );
            acceptorCfg.setFilterChainBuilder( new
DefaultIoFilterChainBuilder() );
            acceptorCfg.setThreadModel( threadModel );

            ((SocketSessionConfig)(acceptorCfg.getSessionConfig())).setTcpNoDelay(
true );

            logger.debug("Port String : " + portString);
            logger.debug("Protocol Prpvider : " + protocolProvider);
            logger.debug("AcceptorConfig : " + acceptorCfg);
            logger.debug("tcpAcceptor : " + tcpAcceptor);

            tcpAcceptor = new SocketAcceptor();

            //try 3 times?
            for (int i=0;i<3;i++) {
            	try {
            		tcpAcceptor.bind( new InetSocketAddress(
Integer.parseInt(portString) ), protocolProvider.getHandler(),
acceptorCfg );
            		break;
            	} catch (java.net.BindException e) {
            		logger.error("Could not bind to address",e);
            	}
            }

			
			/*minaRegistry = new SimpleServiceRegistry();
			Service service = new Service( "ldap", TransportType.SOCKET, new
InetSocketAddress( Integer.parseInt(portString) ) );
			*/
			logger.debug("LDAP listener started");

and here is my stop code

try
        {
            // we should unbind the service before we begin sending the notice
            // of disconnect so new connections are not formed while we process
            List writeFutures = new ArrayList();

            // If the socket has already been unbound as with a successful
            // GracefulShutdownRequest then this will complain that the service
            // is not bound - this is ok because the GracefulShutdown
has already
            // sent notices to to the existing active sessions
            List sessions = null;
            try
            {
                sessions = new ArrayList(
tcpAcceptor.getManagedSessions( new InetSocketAddress( port ) ) );
            }
            catch ( IllegalArgumentException e )
            {
                logger.warn( "Seems like the LDAP service (" + port +
") has already been unbound." );
                return;
            }

            tcpAcceptor.unbind( new InetSocketAddress( port ) );
            if ( logger.isInfoEnabled() )
            {
            	logger.info( "Unbind of an LDAP service (" + port + ") is
complete." );
            	logger.info( "Sending notice of disconnect to existing
clients sessions." );
            }

            // Send Notification of Disconnection messages to all
connected clients.
            if ( sessions != null )
            {
                for ( Iterator i = sessions.iterator(); i.hasNext(); )
                {
                    IoSession session = ( IoSession ) i.next();
                    writeFutures.add( session.write(
NoticeOfDisconnect.UNAVAILABLE ) );
                }
            }

            // And close the connections when the NoDs are sent.
            Iterator sessionIt = sessions.iterator();
            for ( Iterator i = writeFutures.iterator(); i.hasNext(); )
            {
                WriteFuture future = ( WriteFuture ) i.next();
                future.join( 1000 );
                ( ( IoSession ) sessionIt.next() ).close();
            }
        }
        catch ( Exception e )
        {
        	logger.warn( "Failed to sent NoD.", e );
        }

Both snippets were taken nearly verbatim from the apacheds class.

The issue only occurs if I have had clients connect to my server.  For
instance if I just start the server, stop it then start it again it
works just fine.  However if I start the server, run a search and then
stop it again this problem ocurrs.  As a side note, this server was
originally written against apacheds 0.9.8 and which ever version of
MINA that version came with and I never ran into this problem.  Any
help would be greatly appreciated.

Thanks!

Marc

Mime
View raw message