You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Jorge Sousa <jo...@wit-software.com> on 2010/01/11 19:48:16 UTC

Define Global Timeout [S2]

Hi,

First of all sorry for my bad english :)
I need to implement a feature in my application, that will enable me to 
define the timeout of every request.
I tried to create a Interceptor and put the main thread on wait, while 
other 2 threads, one will handle the time, and the other will make the 
invocation.invoke(). The first of this two threads to complete, will 
call the notify of the main thread and the correspondent result is returned.

I tried this approach, but i get a null pointer exception in the thread 
that tried to execute the invocation.invoke().

Is there any suggestions?

If some one need more explanations, please let me know.
You can find the code bellow.

Thanks in advance,
Jorge Sousa from Portugal

Code:

public class TimeoutInterceptor extends AbstractInterceptor {

     private static final ExecutorService threadPool = 
Executors.newCachedThreadPool();

     @Override
     public String intercept(ActionInvocation invocation) throws Exception {
         Invocator invocator = new Invocator(invocation, this);
         TimeoutWatcher timeoutWatcher = new TimeoutWatcher(this);

         threadPool.execute(invocator);
         threadPool.execute(timeoutWatcher);

         this.wait();
         if (invocator.getResult().equalsIgnoreCase("running")) {
             throw new TimeOutException();
         } else {
             return invocator.getResult();
         }

     }

     private class TimeoutWatcher implements Runnable {

         private AbstractInterceptor abstractInterceptor;

         public TimeoutWatcher(AbstractInterceptor abstractInterceptor) {
             this.abstractInterceptor = abstractInterceptor;
         }

         @Override
         public void run() {
             try {
                 Thread.sleep(10000);
             } catch (InterruptedException e) {
             }
             synchronized (abstractInterceptor) {
                 abstractInterceptor.notify();
             }
         }
     }

     private class Invocator implements Runnable {

         private ActionInvocation invocation;
         private String result = "running";
         private AbstractInterceptor abstractInterceptor;

         public Invocator(ActionInvocation invocation, 
AbstractInterceptor abstractInterceptor) {
             this.invocation = invocation;
             this.abstractInterceptor = abstractInterceptor;
         }

         @Override
         public void run() {
             try {
                 result = invocation.invoke();
                 synchronized (abstractInterceptor) {
                     abstractInterceptor.notify();
                 }
             } catch (Exception e) {
                 result = "error";
             }
         }

         public String getResult() {
             return result;
         }
     }

}






Re: Define Global Timeout [S2]

Posted by Jorge Sousa <jo...@wit-software.com>.
Hi,

I can´t change the Tomcat, and i don´t think that change the Tomcat will 
help me to accomplish the feature that i want.

My action does several call's to a external API, and i want to ensure 
that all the call's won't exceed the time that i defined in the timeout.
Changing the Tomcat, will only works for each request, instead of the 
total time of the execution of the action.

I hope this extra information is usefull to help everyone helping me :)

Thanks.

Jorge

On 11-01-2010 19:54, Brian Thompson wrote:
> Honestly, this sounds like something that should be handled at the
> application server level.  What server are you using?
>
> If you're using Tomcat via the Tomcat connector, take a look at reply
> timeouts on [1].
>
> If you're not using Tomcat, I'm sure there are similar options in other app
> servers.
>
> -Brian
>
> [1] - http://tomcat.apache.org/connectors-doc/generic_howto/timeouts.html
>
>
> On Mon, Jan 11, 2010 at 12:48 PM, Jorge Sousa
> <jo...@wit-software.com>wrote:
>
>    
>> Hi,
>>
>> First of all sorry for my bad english :)
>> I need to implement a feature in my application, that will enable me to
>> define the timeout of every request.
>> I tried to create a Interceptor and put the main thread on wait, while
>> other 2 threads, one will handle the time, and the other will make the
>> invocation.invoke(). The first of this two threads to complete, will call
>> the notify of the main thread and the correspondent result is returned.
>>
>> I tried this approach, but i get a null pointer exception in the thread
>> that tried to execute the invocation.invoke().
>>
>> Is there any suggestions?
>>
>> If some one need more explanations, please let me know.
>> You can find the code bellow.
>>
>> Thanks in advance,
>> Jorge Sousa from Portugal
>>
>> Code:
>>
>> public class TimeoutInterceptor extends AbstractInterceptor {
>>
>>     private static final ExecutorService threadPool =
>> Executors.newCachedThreadPool();
>>
>>     @Override
>>     public String intercept(ActionInvocation invocation) throws Exception {
>>         Invocator invocator = new Invocator(invocation, this);
>>         TimeoutWatcher timeoutWatcher = new TimeoutWatcher(this);
>>
>>         threadPool.execute(invocator);
>>         threadPool.execute(timeoutWatcher);
>>
>>         this.wait();
>>         if (invocator.getResult().equalsIgnoreCase("running")) {
>>             throw new TimeOutException();
>>         } else {
>>             return invocator.getResult();
>>         }
>>
>>     }
>>
>>     private class TimeoutWatcher implements Runnable {
>>
>>         private AbstractInterceptor abstractInterceptor;
>>
>>         public TimeoutWatcher(AbstractInterceptor abstractInterceptor) {
>>             this.abstractInterceptor = abstractInterceptor;
>>         }
>>
>>         @Override
>>         public void run() {
>>             try {
>>                 Thread.sleep(10000);
>>             } catch (InterruptedException e) {
>>             }
>>             synchronized (abstractInterceptor) {
>>                 abstractInterceptor.notify();
>>             }
>>         }
>>     }
>>
>>     private class Invocator implements Runnable {
>>
>>         private ActionInvocation invocation;
>>         private String result = "running";
>>         private AbstractInterceptor abstractInterceptor;
>>
>>         public Invocator(ActionInvocation invocation, AbstractInterceptor
>> abstractInterceptor) {
>>             this.invocation = invocation;
>>             this.abstractInterceptor = abstractInterceptor;
>>         }
>>
>>         @Override
>>         public void run() {
>>             try {
>>                 result = invocation.invoke();
>>                 synchronized (abstractInterceptor) {
>>                     abstractInterceptor.notify();
>>                 }
>>             } catch (Exception e) {
>>                 result = "error";
>>             }
>>         }
>>
>>         public String getResult() {
>>             return result;
>>         }
>>     }
>>
>> }
>>
>>
>>
>>
>>
>>
>>      
>    


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Define Global Timeout [S2]

Posted by Brian Thompson <el...@gmail.com>.
Honestly, this sounds like something that should be handled at the
application server level.  What server are you using?

If you're using Tomcat via the Tomcat connector, take a look at reply
timeouts on [1].

If you're not using Tomcat, I'm sure there are similar options in other app
servers.

-Brian

[1] - http://tomcat.apache.org/connectors-doc/generic_howto/timeouts.html


On Mon, Jan 11, 2010 at 12:48 PM, Jorge Sousa
<jo...@wit-software.com>wrote:

> Hi,
>
> First of all sorry for my bad english :)
> I need to implement a feature in my application, that will enable me to
> define the timeout of every request.
> I tried to create a Interceptor and put the main thread on wait, while
> other 2 threads, one will handle the time, and the other will make the
> invocation.invoke(). The first of this two threads to complete, will call
> the notify of the main thread and the correspondent result is returned.
>
> I tried this approach, but i get a null pointer exception in the thread
> that tried to execute the invocation.invoke().
>
> Is there any suggestions?
>
> If some one need more explanations, please let me know.
> You can find the code bellow.
>
> Thanks in advance,
> Jorge Sousa from Portugal
>
> Code:
>
> public class TimeoutInterceptor extends AbstractInterceptor {
>
>    private static final ExecutorService threadPool =
> Executors.newCachedThreadPool();
>
>    @Override
>    public String intercept(ActionInvocation invocation) throws Exception {
>        Invocator invocator = new Invocator(invocation, this);
>        TimeoutWatcher timeoutWatcher = new TimeoutWatcher(this);
>
>        threadPool.execute(invocator);
>        threadPool.execute(timeoutWatcher);
>
>        this.wait();
>        if (invocator.getResult().equalsIgnoreCase("running")) {
>            throw new TimeOutException();
>        } else {
>            return invocator.getResult();
>        }
>
>    }
>
>    private class TimeoutWatcher implements Runnable {
>
>        private AbstractInterceptor abstractInterceptor;
>
>        public TimeoutWatcher(AbstractInterceptor abstractInterceptor) {
>            this.abstractInterceptor = abstractInterceptor;
>        }
>
>        @Override
>        public void run() {
>            try {
>                Thread.sleep(10000);
>            } catch (InterruptedException e) {
>            }
>            synchronized (abstractInterceptor) {
>                abstractInterceptor.notify();
>            }
>        }
>    }
>
>    private class Invocator implements Runnable {
>
>        private ActionInvocation invocation;
>        private String result = "running";
>        private AbstractInterceptor abstractInterceptor;
>
>        public Invocator(ActionInvocation invocation, AbstractInterceptor
> abstractInterceptor) {
>            this.invocation = invocation;
>            this.abstractInterceptor = abstractInterceptor;
>        }
>
>        @Override
>        public void run() {
>            try {
>                result = invocation.invoke();
>                synchronized (abstractInterceptor) {
>                    abstractInterceptor.notify();
>                }
>            } catch (Exception e) {
>                result = "error";
>            }
>        }
>
>        public String getResult() {
>            return result;
>        }
>    }
>
> }
>
>
>
>
>
>

Re: Define Global Timeout [S2]

Posted by Gabriel Belingueres <be...@gmail.com>.
I don't know if you can make this work.

IIRC, interceptor instances are created one by interceptor stack, so
the same instance is shared by all requests that go through that
stack. This makes the interceptor (at best) serialize all requests in
its wait-notify cycle. However, I think it is buggy since the notify()
can wake up any other waiting thread, not the one that created the 2
worker threads: you may assign a unique value to each interceptor call
to associate to the 2 workers for identifying who need to wake and who
need to go to sleep again.

Java monitors uses signal and continue semantics, so you need to
precede the wait with a while loop:
while (justAwakedThreadId != currentId) { wait() }

Also, I think you can safely replace the watchdog thread with just a
call to wait(milliseconds).

One last point to consider is what to do with the generated response,
you may want to implement certain logic inside a PreResultListener to
determine what to do?

HTH

2010/1/11 Jorge Sousa <jo...@wit-software.com>:
> Hi,
>
> First of all sorry for my bad english :)
> I need to implement a feature in my application, that will enable me to
> define the timeout of every request.
> I tried to create a Interceptor and put the main thread on wait, while other
> 2 threads, one will handle the time, and the other will make the
> invocation.invoke(). The first of this two threads to complete, will call
> the notify of the main thread and the correspondent result is returned.
>
> I tried this approach, but i get a null pointer exception in the thread that
> tried to execute the invocation.invoke().
>
> Is there any suggestions?
>
> If some one need more explanations, please let me know.
> You can find the code bellow.
>
> Thanks in advance,
> Jorge Sousa from Portugal
>
> Code:
>
> public class TimeoutInterceptor extends AbstractInterceptor {
>
>    private static final ExecutorService threadPool =
> Executors.newCachedThreadPool();
>
>    @Override
>    public String intercept(ActionInvocation invocation) throws Exception {
>        Invocator invocator = new Invocator(invocation, this);
>        TimeoutWatcher timeoutWatcher = new TimeoutWatcher(this);
>
>        threadPool.execute(invocator);
>        threadPool.execute(timeoutWatcher);
>
>        this.wait();
>        if (invocator.getResult().equalsIgnoreCase("running")) {
>            throw new TimeOutException();
>        } else {
>            return invocator.getResult();
>        }
>
>    }
>
>    private class TimeoutWatcher implements Runnable {
>
>        private AbstractInterceptor abstractInterceptor;
>
>        public TimeoutWatcher(AbstractInterceptor abstractInterceptor) {
>            this.abstractInterceptor = abstractInterceptor;
>        }
>
>        @Override
>        public void run() {
>            try {
>                Thread.sleep(10000);
>            } catch (InterruptedException e) {
>            }
>            synchronized (abstractInterceptor) {
>                abstractInterceptor.notify();
>            }
>        }
>    }
>
>    private class Invocator implements Runnable {
>
>        private ActionInvocation invocation;
>        private String result = "running";
>        private AbstractInterceptor abstractInterceptor;
>
>        public Invocator(ActionInvocation invocation, AbstractInterceptor
> abstractInterceptor) {
>            this.invocation = invocation;
>            this.abstractInterceptor = abstractInterceptor;
>        }
>
>        @Override
>        public void run() {
>            try {
>                result = invocation.invoke();
>                synchronized (abstractInterceptor) {
>                    abstractInterceptor.notify();
>                }
>            } catch (Exception e) {
>                result = "error";
>            }
>        }
>
>        public String getResult() {
>            return result;
>        }
>    }
>
> }
>
>
>
>
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org