6 Replies Latest reply on Feb 9, 2007 4:28 AM by juha

    Need

    eharoldw

      Hi,

      I have been trying to manage timeout on a stateless session bean. I have a client that is running in eclipse outside of jboss calling in to a running jboss server. The server then makes another call to a local service. I did this double hop because I wanted to test the timeout behavior for both remote and local calls.

      The code looks something like this (a combination of pseudo code and real code used throughout):

      client:
      record start time
      stub = (MyInterface)JBossUtil.find(IP, "MyInterface/remote");
      stub.ping("123);
      log elapsed time

      server:
      public String ping(String value) {
      try {
      return
      ((EzRezBusinessServiceInterface) JBossUtil.find("localhost",
      "MyInterface/local")).ping2(value);
      } catch (Exception e) {
      e.printStackTrace();
      return "error";
      }
      }

      public String ping2(String value) {
      for (int i = 0; i < 10; i++) {
      try {
      Thread.sleep(1000);
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      }
      return value;
      }

      The find routine that both teh client and server use does the following:
      Properties properties = new Properties();
      //
      properties.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY,
      "org.jnp.interfaces.NamingContextFactory");
      properties.put(javax.naming.Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
      properties.put(javax.naming.Context.PROVIDER_URL, providerUrl);
      properties.put("jnp.disableDiscovery", (disableDiscovery == true) ? "true" : "false");
      properties.put("jnp.timeout", "250"); // connection timeout in milliseconds
      properties.put("jnp.sotimeout", "500"); // socket read timeout in milliseconds
      //
      return new InitialContext(properties).lookup(interfaceName);

      The behavior is that the client always return in 10 seconds, as determined by the time taken to execute ping2.

      I am trying to figure out how to change the timeout so that I can control this. I.e., I would like to be able to set something so that the client gets a timeout exception if the call takes more than 5 seconds.

      I have tried setting the socket timeout in jboss-service.xml, and the transaction timeout in jta-service.xml. In the latter case, I can see some logs warning about transaction timeouts, but the client still takes 10 seconds to execute and seems to simply return the ping value rather than any timeout indications.

      Can you help me know what configurations I should change to control the response time from a service call?

      It would be ideal if I could control on individual calls in an interface. (I.e., ping1 must respond in 5 seconds but ping2 may take 10 seconds), but I won't be greedy right now. :-)

      Thanks,

      Harold Williams

        • 1. Re: Need

          This is probably best achieved by customizing the EJB container with your own interceptor.

          • 2. Re: Need
            eharoldw

            In order to do this with an interceptor, would I not have to make a separate thread? Otherwise, how could my interceptor gain control to throw an exception if it has chained on to code that does not return in the allotted time?

            Creating a new thread is worrisome since interceptor state is held on the thread, right?

            I guess I am not quite sure what your suggestion is>

            Thanks,

            Harold

            • 3. Re: Need

               

              "eharoldw" wrote:
              In order to do this with an interceptor, would I not have to make a separate thread?


              yes.

              most state is held in the invocation object with couple of notable exceptions (security, tx on the thread), so basically you could disconnect your incoming thread from the actual worker thread by passing the invocation on -- you can return the calling thread based on your timeout and appropriate timeout indicators and let the worker thread die eventually if it didn't finish within the given time limit.

              this however is going well beyond the EJB component contract and the expected behavior which is why a custom container (via interceptors) is probably what you should do (clean break from EJB component model) -- you may even be best doing this with purely POJO and/or AOP containers rather than EJB, depending on how much you rely on the other existing services the EJB spec provides (tx, sec, concurrency, pooling, etc).

              hope it helps

              • 4. Re: Need

                And to add to the previous -- if you can already go with EJB3 then the JBoss EJB3 async invocations with future return values may be the least effort solution to your problem

                • 5. Re: Need
                  eharoldw

                  I was hoping that there was some configuration I could set so that if an invocation took more than a certain amount of time it would automatically throw an exception. It sounds as if you are saying there is not such configuration and offer a couple of alternatives.

                  One alternative is to create a thread in an interceptor and have the work done in that new thread. The interceptor could wait on that thread with a timeout and throw and excpetion if the thread does not return in time. I can see how that would work, but it would double the number of threads in our system, which worries me.

                  The other alternative is to program with futures. I am not quite clear how to do this, but I suspect it is an approach we would not want. We like the api to be synchronous from the client point of view. Also, the api is quite large, so I suspect there would be a lrage number of changes to make this work.

                  Could you say if I am reading your responses correctly? I appreciate your help. Unfortunately, I am not sure that either of these approaches are ones we want to take.

                  Thanks,

                  Harold

                  • 6. Re: Need

                     

                    "eharoldw" wrote:
                    I was hoping that there was some configuration I could set so that if an invocation took more than a certain amount of time it would automatically throw an exception.


                    I'm not aware of it -- it doesn't mean some developer hasn't added it at some point but if they did, they didn't make a lot of noise about it ;-) It wouldn't change the underlying problem of having a timer thread on the server to measure the invocation times though.

                    "eharoldw" wrote:

                    Could you say if I am reading your responses correctly?


                    Yes. I still think using the JBoss EJB3 async API might be the "cheapest" solution (in terms of development time) and you could hide the semantics behind a synchronous client API.

                    Alternatively, if EJB3 is not an option, and you worry about the thread count on the server, you can have the interceptor in the client proxy instead, and do the thread disconnect already on the client VM (so the additional thread management is distributed across client VMs). This is likely similar to the behavior of JBoss EJB3 async API with EJB2 proxies.