Home | About | Sematext search-lucene.com search-hadoop.com
 Search Hadoop and all its subprojects:

Switch to Threaded View
Avro >> mail # user >> SaslSocketServer.close() doesn't close?


Copy link to this message
-
Re: SaslSocketServer.close() doesn't close?
Hi Alex,

The test you posted works fine for me, even using a sleep time as short as
5ms between closing and reopening.

Looking at trunk, the code to close the socket is in the finally block
inside SocketServer.run().  When close() is called it sends an interrupt to
the SocketServer thread, which causes the channel.accept() call to unblock
and throw java.nio.channels.ClosedByInterruptException.
ClosedByInterruptException is a ClosedChannelException, which is caught
inside the channel.accept() try/catch block and causes the run() method to
return.  Before the method returns, the finally block fires, which closes
the channel.  You should be able to verify that the finally block is called
when you see the "INFO org.apache.avro.ipc.SocketServer - stopping" log
message.  One improvement that could be made to this code is modifying the
close() method to block until the socket has finished closing.  An
overloaded close(Boolean) could be added that takes a flag indicating
whether the call should return immediately or block until the socket has
closed.

10 seconds is a long time, but does your test pass if you increase the sleep
time?  Do you ever see the "stopping" log message?  Can you step through
your test in a debugger and see what's happening inside SocketServer when
you call close()?  What is your environment like?  JVM version, Linux distro
and kernel, etc.

-James
On Mon, Jun 13, 2011 at 12:37 PM, Alex Miller <[EMAIL PROTECTED]> wrote:

> Hello all,
>
> I've been having an issue in some tests where it appears that closing
> a SaslSocketServer does not actually cause the socket to be closed.
> The code below reproduces roughly what happens in the course of a much
> more complicated test.  Basically I start a socket server, close() it,
> then try to start another on the same port which fails to bind as the
> address is in use.
>
> From trolling through the code, it is not immediately obvious that any
> code exists to actually close the socket.  The nio thread group gets
> interrupted which from debugging into this, does seem to cause the
> Connection threads to break out of their loop and close but the main
> socket listener (which is not a member of the thread group) and the
> socket channel do not get closed.
>
> Am I crazy?
>
>
>
> import java.net.InetAddress;
> import java.net.InetSocketAddress;
>
> import org.apache.avro.Protocol;
> import org.apache.avro.Schema;
> import org.apache.avro.Protocol.Message;
> import org.apache.avro.io.Decoder;
> import org.apache.avro.io.Encoder;
> import org.apache.avro.ipc.Responder;
> import org.apache.avro.ipc.SaslSocketServer;
> import org.apache.avro.ipc.Server;
>
> public class SocketDoesntClose extends Responder {
>
>  public static void main(String[] args) throws Exception {
>
>    Protocol prot = new Protocol("c", "a.b");
>
>    // start on port 9999
>    InetSocketAddress addr = new
> InetSocketAddress(InetAddress.getLocalHost(), 9999);
>    Server server = new SaslSocketServer(new SocketDoesntClose(prot), addr);
>    server.start();
>
>    // stop -- I would expect this to fully release the socket
>    server.close();
>
>    Thread.sleep(10000);
>
>    // start on same socket again -> address already in use
>    server = new SaslSocketServer(new SocketDoesntClose(prot), addr);
>  }
>
>  // dummy implementation
>  public SocketDoesntClose(Protocol local) {
>    super(local);
>  }
>
>  public Object readRequest(Schema actual, Schema expected, Decoder in) {
>    return null;
>  }
>
>  public Object respond(Message message, Object request) {
>    return null;
>  }
>
>  public void writeError(Schema schema, Object error, Encoder out) {
>  }
>
>  public void writeResponse(Schema schema, Object response, Encoder out) {
>  }
> }
>