You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by Marc Boorshtein <mb...@gmail.com> on 2006/12/26 18:49:40 UTC

TCP service not shutting down cleanly

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

Re: TCP service not shutting down cleanly

Posted by Marc Boorshtein <mb...@gmail.com>.
>
> Ah I see.  Then isn't it a problem of JVM rather than of MINA?
>

I don't think so because I never had (and still don't have) this issue
with the MINA that came with ApacheDS 0.9.8

> It is really weird, but I guess we don't have any control on it if it only
> occurs when you kill (i.e. kill -9 <pid>) the process.
>

I'm not a network stack expert, but if I had to guess I think the
issue is probably more on how the connection is oppened and managed
wrather then how it is shut down.

This was really only an issue because it kept me from running my unit
tests which I've been able to clear up by making sure I cleanly
shutdown MyVD at the end of every run.

Marc

Re: TCP service not shutting down cleanly

Posted by Trustin Lee <tr...@gmail.com>.
On 1/30/07, Marc Boorshtein <mb...@gmail.com> wrote:
>
> On 1/30/07, Trustin Lee <tr...@gmail.com> wrote:
> > I attached some test code for reproducing the problem.
> >
> >  https://issues.apache.org/jira/browse/DIRMINA-342
> >
> > So far, I couldn't reproduce the problem using it, but I believe what it
> > does is almost same with what ApacheDS does.  I suspect it is a platform
> > dependent problem which is not directly related with MINA.
> >
>
> Sorry I haven't had a chance to follow up on this,  The shutdown code
> from apacheds is working well.  The issue only seems to occur when the
> process is killed before the shutdown code can be executed.


Ah I see.  Then isn't it a problem of JVM rather than of MINA?

The issue does occur on both Fedora Core 5 and Fedora Core 6.  The
> only thing that would have me disagree with your assertion is that I
> didn't have this issue with the MINA that came with apacheds 0.9.8.


It is really weird, but I guess we don't have any control on it if it only
occurs when you kill (i.e. kill -9 <pid>) the process.

> Marc, please run the test code I've created and let me know the result and
> > the difference from the real scenario, if there's any difference.  And,
> > please try again with the latest snapshot ( 1.0.2-SNAPSHOT).
>
> Will probably not be able to get to this until this weekend, but will do.


OK.  Then let me reschedule this issue to 1.0.3, and start the vote to
release 1.0.2. :)

Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP key fingerprints:
* E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
* B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6

Re: TCP service not shutting down cleanly

Posted by Marc Boorshtein <mb...@gmail.com>.
On 1/30/07, Trustin Lee <tr...@gmail.com> wrote:
> I attached some test code for reproducing the problem.
>
>  https://issues.apache.org/jira/browse/DIRMINA-342
>
> So far, I couldn't reproduce the problem using it, but I believe what it
> does is almost same with what ApacheDS does.  I suspect it is a platform
> dependent problem which is not directly related with MINA.
>

Sorry I haven't had a chance to follow up on this,  The shutdown code
from apacheds is working well.  The issue only seems to occur when the
process is killed before the shutdown code can be executed.

The issue does occur on both Fedora Core 5 and Fedora Core 6.  The
only thing that would have me disagree with your assertion is that I
didn't have this issue with the MINA that came with apacheds 0.9.8.


> Marc, please run the test code I've created and let me know the result and
> the difference from the real scenario, if there's any difference.  And,
> please try again with the latest snapshot ( 1.0.2-SNAPSHOT).
>

Will probably not be able to get to this until this weekend, but will do.

Thanks for the follow up!

Marc

Re: TCP service not shutting down cleanly

Posted by Trustin Lee <tr...@gmail.com>.
I attached some test code for reproducing the problem.

https://issues.apache.org/jira/browse/DIRMINA-342

So far, I couldn't reproduce the problem using it, but I believe what it
does is almost same with what ApacheDS does.  I suspect it is a platform
dependent problem which is not directly related with MINA.

Marc, please run the test code I've created and let me know the result and
the difference from the real scenario, if there's any difference.  And,
please try again with the latest snapshot (1.0.2-SNAPSHOT).

HTH,
Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP key fingerprints:
* E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
* B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6

Re: TCP service not shutting down cleanly

Posted by Trustin Lee <tr...@gmail.com>.
I created a JIRA issue regarding the problem:

http://issues.apache.org/jira/browse/DIRMINA-342

Trustin

On 12/27/06, Marc Boorshtein <mb...@gmail.com> wrote:
>
> 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
>



-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP key fingerprints:
* E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
* B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6

Re: TCP service not shutting down cleanly

Posted by Emmanuel Lecharny <el...@gmail.com>.
Hi Marc,

I'm on Fedora Core 5 at home, and Ubuntu 6.10 or Mac OS/X at office.

Feel free to fill a JIRA, so that we will still have an eye on it. When it
will be fixed, we will just close it.
(better have a JIRA than a mail lost in zillions of mails :)

Emmanuel

On 12/29/06, Marc Boorshtein <mb...@gmail.com> wrote:
>
> >
> > Make sure you're using the following parameters to the acceptor config.
> >  Namely the reuse address true parameter.
>
> Thanks Alex, but that does match my code.  What OS/jdk do you guys
> test on?  I'm on Fedora Core 5/jdk 1.5.something.  Since I don't have
> this issue with the mina that comes with apacheds 0.9.8 I'll see if I
> need to register a bug with the mina project and revisit once it's
> taken care of.
>
> Thanks everyone.
>
> Marc
>



-- 
Cordialement,
Emmanuel Lécharny
www.iktek.com

Re: TCP service not shutting down cleanly

Posted by Marc Boorshtein <mb...@gmail.com>.
>
> Make sure you're using the following parameters to the acceptor config.
>  Namely the reuse address true parameter.

Thanks Alex, but that does match my code.  What OS/jdk do you guys
test on?  I'm on Fedora Core 5/jdk 1.5.something.  Since I don't have
this issue with the mina that comes with apacheds 0.9.8 I'll see if I
need to register a bug with the mina project and revisit once it's
taken care of.

Thanks everyone.

Marc

Re: TCP service not shutting down cleanly

Posted by Alex Karasulu <ak...@apache.org>.
Marc Boorshtein wrote:
>> Well, this is a rampant problem we have, and it don't want to vanish...
> 
> Odd, why didn't this happen in the original version I used?
> 
>> If you are on linux, you can modify you TCP keepalive parameter to a
>> smaller
>> value, so the socket will be freed faster.
>>
> 
> This didn't work.  How does the ApacheDS team handle this issue in
> it's automated tests?
> 
>> The problem might be that you violently stop the server, and some sockets
>> are still pending, waiting for a timeout. If you gently stop the server,
>> then I *think* mina closes all the opened socket nicely, and left the
>> socket
>> available immediatly. To be verified...
>>
> 
> Was the code I was using to stop my server incorrect?
> 

Hmmm I did not have a chance to look thoroughly at the code.  However
there is a paramter for MINA that we do use that may help you.  Look
here ...

            // Disable the disconnection of the clients on unbind
            SocketAcceptorConfig acceptorCfg = new SocketAcceptorConfig();
            acceptorCfg.setDisconnectOnUnbind( false );
            acceptorCfg.setReuseAddress( true );
            acceptorCfg.setFilterChainBuilder( chainBuilder );
            acceptorCfg.setThreadModel( threadModel );


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

            tcpAcceptor.bind( new InetSocketAddress( port ),
protocolProvider.getHandler(), acceptorCfg );


Make sure you're using the following parameters to the acceptor config.
 Namely the reuse address true parameter.

HTH,
Alex

Re: TCP service not shutting down cleanly

Posted by Marc Boorshtein <mb...@gmail.com>.
> Well, this is a rampant problem we have, and it don't want to vanish...

Odd, why didn't this happen in the original version I used?

> If you are on linux, you can modify you TCP keepalive parameter to a smaller
> value, so the socket will be freed faster.
>

This didn't work.  How does the ApacheDS team handle this issue in
it's automated tests?

> The problem might be that you violently stop the server, and some sockets
> are still pending, waiting for a timeout. If you gently stop the server,
> then I *think* mina closes all the opened socket nicely, and left the socket
> available immediatly. To be verified...
>

Was the code I was using to stop my server incorrect?

Thanks

Re: TCP service not shutting down cleanly

Posted by Emmanuel Lecharny <el...@gmail.com>.
Well, this is a rampant problem we have, and it don't want to vanish...

If you are on linux, you can modify you TCP keepalive parameter to a smaller
value, so the socket will be freed faster.

The problem might be that you violently stop the server, and some sockets
are still pending, waiting for a timeout. If you gently stop the server,
then I *think* mina closes all the opened socket nicely, and left the socket
available immediatly. To be verified...

Emmanuel


On 12/26/06, Marc Boorshtein <mb...@gmail.com> wrote:
>
> 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
>



-- 
Cordialement,
Emmanuel Lécharny
www.iktek.com

Re: TCP service not shutting down cleanly

Posted by Emmanuel Lecharny <el...@gmail.com>.
Well, this is a rampant problem we have, and it don't want to vanish...

If you are on linux, you can modify you TCP keepalive parameter to a smaller
value, so the socket will be freed faster.

The problem might be that you violently stop the server, and some sockets
are still pending, waiting for a timeout. If you gently stop the server,
then I *think* mina closes all the opened socket nicely, and left the socket
available immediatly. To be verified...

Emmanuel


On 12/26/06, Marc Boorshtein <mb...@gmail.com> wrote:
>
> 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
>



-- 
Cordialement,
Emmanuel Lécharny
www.iktek.com

Re: TCP service not shutting down cleanly

Posted by Trustin Lee <tr...@gmail.com>.
I created a JIRA issue regarding the problem:

http://issues.apache.org/jira/browse/DIRMINA-342

Trustin

On 12/27/06, Marc Boorshtein <mb...@gmail.com> wrote:
>
> 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
>



-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP key fingerprints:
* E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
* B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6