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 Sudhan,

The parts of SocketServer that we need to examine are the run() and close()
methods.  Removing everything but the core functionality, these methods look
something like this (in trunk):

public void run() {
  try {
    while (true) {
      try {
        new Connection(channel.accept());
      } catch (ClosedChannelException e) {
        return;  // caught when the SocketServer thread is interrupted in
  } finally {
    channel.close(); // channel is always closed before run() returns

public void close() {
  this.interrupt(); // interrupts the SocketServer
  group.interrupt(); // interrupts the connection thread group

The first statement in the close() method interrupts the SocketServer
thread, which causes that thread to break out of the channel.accept() call
and the while loop in the run() method (after catching
ClosedChannelException).  When the finally block runs, the channel will be
closed.  The SocketServer thread does not need to be added to the thread
group because there is a separate interrupt call for the SocketServer thread

I made a JUnit test from Alex's example and modified it to join on the
SocketServer after calling close(), as you suggested.  This doesn't hang for
me, and it doesn't throw any exceptions when re-binding to the same port.
The test I ran is here:


Can you try running that to see if you get the same result?  By the way,
what version of Avro are you using?  Is it something other than trunk?
Maybe that explains the difference in behavior.

On Tue, Jun 14, 2011 at 1:38 AM, Sudharsan Sampath <[EMAIL PROTECTED]>wrote:

> I don't see the daemon SocketServer thread that was created as part of the
> server.start() call added to the 'group' ThreadGroup. Only any new
> connections that the socket accepts are added to the threadGroup and only
> these are the ones that will get interrupted on the close call.
> In our example with no clients requesting access, the thread group array
> remains empty and send no interrupt at all. Could this be the issue for the
> server to hang indefinitely?
> -Sudhan S
> On Tue, Jun 14, 2011 at 10:35 AM, Sudharsan Sampath <[EMAIL PROTECTED]>wrote:
>> Hi,
>> I tried but have the same issue. I added server.join() after the close
>> call instead of waiting for a pre-defined time. But it hangs indefinitely.
>> -Sudhan S
>> On Mon, Jun 13, 2011 at 10:07 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