4 Replies Latest reply on Nov 15, 2008 1:58 AM by jaikiran pai

    Remoting 2.5 SP1 - ServerInvoker.TIMEOUT does not work?

    jaikiran pai Master

      I am trying out a few examples with JBossRemoting 2.5 SP1 version. I have the following piece of code which creates a socket Connector and tries to set a timeout (for the internal socket accept() call) to 3 seconds:

      String uri = "socket://" + serverHost + ":" + port;
       InvokerLocator invokerLocator = new InvokerLocator(uri);
      
       this.remoteConnector = new Connector(invokerLocator);
       this.remoteConnector.create();
      
       ;
       this.remoteConnector.addInvocationHandler("sample", new MyInvocationHandler());
      
       // SET THE TIMEOUT AND START TO WAIT FOR CLIENTS
       this.remoteConnector.getServerInvoker().setTimeout(3000);
       this.remoteConnector.start();
      



      On the client side, i intentionally add a Thread.sleep for 15 seconds, before connecting to the server:

      uri = "socket://" + this.serverHost + ":" + this.port;
      InvokerLocator invokerLocator = new InvokerLocator(uri);
      client= new Client(invokerLocator);
      
      // sleep for 15 sec to test timeout on server
       Thread.sleep(15000);
       // now connect and invoke
       client.connect();
      
      client.invoke("blahblah");
      
      


      However, the call to this.remoteConnector.start() on the server never timesout. It just waits (forever) till the client connects to the server. It does not even timeout after the default timeout that the documentation mentions:
      The default timeout value is 60000 for server invokers.


      Am i missing something with this timeout feature? I checked the docs and even tried passing the ServerInvoker.TIMEOUT through the metadata while creating the Connector. Even that did not work.

      I enabled the TRACE level logs of the org.jboss.remoting package to see if i am missing anything. The logs show this:

      20:29:15,979 DEBUG [SocketServerInvoker] SocketServerInvoker[localhost:12345] starting
      20:29:15,995 DEBUG [SocketServerInvoker] SocketServerInvoker[localhost:12345] created ServerSocket[addr=/127.0.0.1,port=0,localport=12345]
      20:29:15,995 TRACE [SocketServerInvoker] SocketServerInvoker[localhost:12345] created Thread[AcceptorThread[ServerSocket[addr=/127.0.0.1,port=0,localport=12345]],5,main]
      20:29:15,995 DEBUG [ServerInvoker] SocketServerInvoker[localhost:12345] started for locator InvokerLocator [socket://localhost:12345/]
      20:29:15,995 DEBUG [SocketServerInvoker] SocketServerInvoker[localhost:12345] started
      20:29:15,995 TRACE [SocketServerInvoker] Thread[AcceptorThread[ServerSocket[addr=/127.0.0.1,port=0,localport=12345]],5,main] started execution of method run()
      20:29:15,995 TRACE [SocketServerInvoker] passed through ServerSocketRefresh.release()
      20:29:15,995 DEBUG [Connector] org.jboss.remoting.transport.Connector@8a0d5d started
      20:29:15,995 TRACE [SocketServerInvoker] Thread[AcceptorThread[ServerSocket[addr=/127.0.0.1,port=0,localport=12345]],5,main] is going to wait on serverSocket.accept()
      
      


      Looking at the code in SocketServerInvoker, i don't see the code using the timeout value. Also i tried looking for testcases in the SVN to see if there is one which tests the timeout on the server side. But i could not find any. I do see test cases for testing the client side timeouts.

      Am i doing something wrong here? Let me know if additional logs or other piece of code is required.

        • 1. Re: Remoting 2.5 SP1 - ServerInvoker.TIMEOUT does not work?
          jaikiran pai Master

          I found a testcase org.jboss.test.remoting.transport.socket.timeout.TimeoutServerTest which is testing the timeout on the invocation handler processing. However, i could not find any test case which checks for timeout setting on

          connector.start(); //should timeout if no client connects in x milli sec


          Let me know, if i have to provide a test case for this.


          • 2. Re: Remoting 2.5 SP1 - ServerInvoker.TIMEOUT does not work?
            jaikiran pai Master

            I tried passing the "timeout" through the configuration map to the connector and then through the invokerlocation URL as a param and even tried calling connector.getServerInvoker().setTimeout(3000). None seem to work. However, the documentation clearly mentions this:


            timeout - The socket timeout value passed to the Socket.setSoTimeout() method. The default on the server side is 60000 (one minute).


            Neither the default timeout nor the user defined timeout seem to be working for the connector.start() method. Looking into the code in the AcceptorThread, i see that this timeout is never used while calling the accept() method on the SocketServer. This results in an indefinitely blocking call.

            I do have a testcase to reproduce this. Now all i am waiting for is a confirmation that this is indeed an issue and not something that i missing :-)

            • 3. Re: Remoting 2.5 SP1 - ServerInvoker.TIMEOUT does not work?
              Ron Sigal Master

              In fact, you've discovered the fact that a timeout value is never set for the ServerSocket in SocketServerInvoker. In fact, there really doesn't seem to be any point to setting the timeout value, since all we would do in the event of a timeout is go back and call ServerSocket.accept() again. In fact, the asynchronous nature of a distributed system suggests that the server should be prepared to wait indefinitely to hear from a client.

              If you look in SocketServerInvoker.run(), you will see two calls to getTimeout(), the result of which is passed to a ServerThread in each case. This timeout value is used to set the timeout value for the Socket through which invocations will arrive from the client. Given that network connections are a relatively scarce resource, it *does* make sense to let these sockets time out if an invocation is not forthcoming, rather than have them wait forever.

              • 4. Re: Remoting 2.5 SP1 - ServerInvoker.TIMEOUT does not work?
                jaikiran pai Master

                Ron, thank you for the explanation!

                "ron.sigal@jboss.com" wrote:
                In fact, you've discovered the fact that a timeout value is never set for the ServerSocket in SocketServerInvoker. In fact, there really doesn't seem to be any point to setting the timeout value, since all we would do in the event of a timeout is go back and call ServerSocket.accept() again.

                When i had looked at the code, i did infact see that the AcceptorThread was just accepting the connection and then the ServerThread was doing the actual work (as explained in the docs too).

                "ron.sigal@jboss.com" wrote:

                In fact, the asynchronous nature of a distributed system suggests that the server should be prepared to wait indefinitely to hear from a client.

                I had been trying out this application with the following usecase:
                - Connector (server) waits for commands (custom commands like startServer, stopServer, getServerStatus) on some url after calling the create and start remoting API
                - Client can connect to the server using Remoting APIs and then send out requests which the ServerInvocationHandler will handle.
                - All this was being done as part of a testcase. So if for some reason, the client never managed to connect to the server, i did not want the testcase to wait forever waiting for a client. That's where i was looking for a timeout functionality on the Conncetor.start() API. I think i will have to revisit my usecase.



                "ron.sigal@jboss.com" wrote:

                If you look in SocketServerInvoker.run(), you will see two calls to getTimeout(), the result of which is passed to a ServerThread in each case. This timeout value is used to set the timeout value for the Socket through which invocations will arrive from the client. Given that network connections are a relatively scarce resource, it *does* make sense to let these sockets time out if an invocation is not forthcoming, rather than have them wait forever.


                Makes sense. Thanks for the explanation :-)