You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by christophe blin <cb...@tennaxia.com> on 2007/11/22 09:38:10 UTC

How to have a request timeout ?

Hi,

I'd like to cancel a servlet request if it took more than 5 seconds.

ATM, I know this is not possible directly via a tomcat configuration (in
fact I found no servlet container with this option).
By googling and doing a lot of tries (mainly based on
http://marc.info/?l=tomcat-user&m=109463824530983&w=2) , I find the
following snippet to be working but I have some problems with it.

1/ it use the deprecated Thread.stop method but I do not know if there is a
way to use interrupt or any safer mecanism

2/ I do not know if this is really the best way to achieve what I want so if
you have some pointers, do not hesitate to give them to me.

thanks,

chris

[code]
public class InterruptFilter implements Filter {
    public void init(FilterConfig arg0) throws ServletException {
    }

    public void destroy() {
    }

    public void doFilter(ServletRequest request, ServletResponse response,
FilterChain fc) throws IOException, ServletException {
        InterruptTimer mTimer = new InterruptTimer(5000, 10,
Thread.currentThread());
        mTimer.start();
        fc.doFilter(request, response);
        mTimer.reset();
    }

    public class InterruptTimer extends Thread {
        long oEndTime = 0;
        int oSleepTime = 10;
        Thread oStartingThread = null;

        public InterruptTimer(int aLength, int aSleepTime, Thread
aStartingThread) {
            // Both times are in ms
            oSleepTime = aSleepTime;
            oEndTime = System.currentTimeMillis() + aLength;
            oStartingThread = aStartingThread;
        }

        public void run() {
            // Loop until the end time is reached or reset() was called.
            while (System.currentTimeMillis() < oEndTime) {
                try {
                    Thread.sleep(oSleepTime);
                } catch (InterruptedException ex) {
                }
            }
            if (oEndTime > 0) {
                timeout();
            }
        }
        public void reset() {
            oEndTime = 0;
        }

        public void timeout() {
            System.out.println("**************** stop the request thread");
            oStartingThread.stop();
        }
    }
}

[/code]
-- 
View this message in context: http://www.nabble.com/How-to-have-a-request-timeout---tf4855066.html#a13892897
Sent from the Tomcat - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: How to have a request timeout ?

Posted by Johnny Kewl <jo...@kewlstuff.co.za>.
---------------------------------------------------------------------------
HARBOR: http://coolharbor.100free.com/index.htm
Now Tomcat is also a cool pojo application server
---------------------------------------------------------------------------
----- Original Message ----- 
From: "christophe blin" <cb...@tennaxia.com>

>
> Hi,
>
> I'd like to cancel a servlet request if it took more than 5 seconds.
>
> ATM, I know this is not possible directly via a tomcat configuration (in
> fact I found no servlet container with this option).
> By googling and doing a lot of tries (mainly based on
> http://marc.info/?l=tomcat-user&m=109463824530983&w=2) , I find the
> following snippet to be working but I have some problems with it.
>
> 1/ it use the deprecated Thread.stop method but I do not know if there is 
> a
> way to use interrupt or any safer mecanism
>
> 2/ I do not know if this is really the best way to achieve what I want so 
> if
> you have some pointers, do not hesitate to give them to me.

I dont like this at all.... if I read it right, its using a thread here as a 
timer, and then killing the actual Tomcat thread... that cant be good.
So if tomcat needs to clean a buffer or do some house keeping, it cant... no 
this can be good.

Have to ask why you cant just let the thread exit normally or let the 
browser timeout, or let the user get bored and close the browser?
ie the scheme is pretty good already... ?

One way that would make sense to me is in the servlet proper... one creates 
a background task, waits for the result, and then stops that.
ie you only messing with your own code... not bombing tomcats engine.
Never used it but SUN seems to have a FutureTask engine made for this sort 
of thing.

I think other than messing with your own code... you cant.

This stuff below I think is trouble ;)

> [code]
> public class InterruptFilter implements Filter {
>    public void init(FilterConfig arg0) throws ServletException {
>    }
>
>    public void destroy() {
>    }
>
>    public void doFilter(ServletRequest request, ServletResponse response,
> FilterChain fc) throws IOException, ServletException {
>        InterruptTimer mTimer = new InterruptTimer(5000, 10,
> Thread.currentThread());
>        mTimer.start();
>        fc.doFilter(request, response);
>        mTimer.reset();
>    }
>
>    public class InterruptTimer extends Thread {
>        long oEndTime = 0;
>        int oSleepTime = 10;
>        Thread oStartingThread = null;
>
>        public InterruptTimer(int aLength, int aSleepTime, Thread
> aStartingThread) {
>            // Both times are in ms
>            oSleepTime = aSleepTime;
>            oEndTime = System.currentTimeMillis() + aLength;
>            oStartingThread = aStartingThread;
>        }
>
>        public void run() {
>            // Loop until the end time is reached or reset() was called.
>            while (System.currentTimeMillis() < oEndTime) {
>                try {
>                    Thread.sleep(oSleepTime);
>                } catch (InterruptedException ex) {
>                }
>            }
>            if (oEndTime > 0) {
>                timeout();
>            }
>        }
>        public void reset() {
>            oEndTime = 0;
>        }
>
>        public void timeout() {
>            System.out.println("**************** stop the request thread");
>            oStartingThread.stop();
>        }
>    }
> }
>
> [/code]
> -- 
> View this message in context: 
> http://www.nabble.com/How-to-have-a-request-timeout---tf4855066.html#a13892897
> Sent from the Tomcat - User mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
> 


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: How to have a request timeout ?

Posted by christophe blin <cb...@tennaxia.com>.
I found the problem: infinite loop of course !

Nevertheless, I think that having a "security" in the servlet container for
such (stupid) things could be great

Thanks for your help.

Chris


-- 
View this message in context: http://www.nabble.com/How-to-have-a-request-timeout---tf4855066.html#a13899022
Sent from the Tomcat - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: How to have a request timeout ?

Posted by Pid <p...@pidster.com>.
christophe blin wrote:
> 
> 
> Pid-2 wrote:
>> Can you elaborate on the reason behind this requirement?
>>
> 
> sure !
> 
> first some background :
> 1/ my servlet is a web service (done with spring exporter and xfire if that
> matters)
> 2/ the client is not a browser but the PHP SOAP extension
> 3/ 5 seconds is the example (in real life, it would be something like 30
> seconds)
> 
> my problem : when the php script times out (max_execution_time of the
> php.ini is reached), the servlet request does not stop...
> As a consequence, I found 5 threads in my tomcat instances which take 100%
> of the CPU and with a lifetime greater than or equals to 123000532ms (that
> make more than 1 day).

You should have a closer look to see what those threads are actually
doing, before you start altering your timeouts.  If it's something in
the servlet that's causing it, then forcing the request to timeout may
not be the answer.

Try taking a thread dump of one of the long-lasting ones and follow the
stack trace to see where it's stuck.

I'm pretty certain you don't want to kill the main thread itself.

p



> so I'd like to know how to stop a request if it takes more than x seconds
> (like the php.ini max_execution_time).
> 
> I know this is surely bad practice but I can not find a way to sort out this
> problem otherwise
> 
> note : sometimes when the php script times out the request is closed, but
> sometimes not... so maybe this is a PHP issue or a PHP Soap extension issue


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: How to have a request timeout ?

Posted by christophe blin <cb...@tennaxia.com>.


Pid-2 wrote:
> 
> Can you elaborate on the reason behind this requirement?
> 

sure !

first some background :
1/ my servlet is a web service (done with spring exporter and xfire if that
matters)
2/ the client is not a browser but the PHP SOAP extension
3/ 5 seconds is the example (in real life, it would be something like 30
seconds)

my problem : when the php script times out (max_execution_time of the
php.ini is reached), the servlet request does not stop...
As a consequence, I found 5 threads in my tomcat instances which take 100%
of the CPU and with a lifetime greater than or equals to 123000532ms (that
make more than 1 day).

so I'd like to know how to stop a request if it takes more than x seconds
(like the php.ini max_execution_time).

I know this is surely bad practice but I can not find a way to sort out this
problem otherwise

note : sometimes when the php script times out the request is closed, but
sometimes not... so maybe this is a PHP issue or a PHP Soap extension issue
-- 
View this message in context: http://www.nabble.com/How-to-have-a-request-timeout---tf4855066.html#a13897171
Sent from the Tomcat - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: How to have a request timeout ?

Posted by Pid <p...@pidster.com>.



christophe blin wrote:
> Hi,
> 
> I'd like to cancel a servlet request if it took more than 5 seconds.
> 
> ATM, I know this is not possible directly via a tomcat configuration (in
> fact I found no servlet container with this option).
> By googling and doing a lot of tries (mainly based on
> http://marc.info/?l=tomcat-user&m=109463824530983&w=2) , I find the
> following snippet to be working but I have some problems with it.

Are you really sure you want to kill a request after 5 seconds?

Do you mean 5 seconds after the connection is opened, or 5 seconds after
the response has begun?

The properties of the http connector element in server.xml allow you to
configure the former, but I'd strongly advise against doing so:

connectionTimeout="5"

See: http://tomcat.apache.org/tomcat-6.0-doc/config/http.html

I can't think of reason why you'd want to interrupt the *response* after
5 seconds, but if you do, then you probably need to run whichever job is
problematic inside a Thread that you interrupt after 5 seconds.

Can you elaborate on the reason behind this requirement?

p



> 1/ it use the deprecated Thread.stop method but I do not know if there is a
> way to use interrupt or any safer mecanism
> 
> 2/ I do not know if this is really the best way to achieve what I want so if
> you have some pointers, do not hesitate to give them to me.
> 
> thanks,
> 
> chris
> 
> [code]
> public class InterruptFilter implements Filter {
>     public void init(FilterConfig arg0) throws ServletException {
>     }
> 
>     public void destroy() {
>     }
> 
>     public void doFilter(ServletRequest request, ServletResponse response,
> FilterChain fc) throws IOException, ServletException {
>         InterruptTimer mTimer = new InterruptTimer(5000, 10,
> Thread.currentThread());
>         mTimer.start();
>         fc.doFilter(request, response);
>         mTimer.reset();
>     }
> 
>     public class InterruptTimer extends Thread {
>         long oEndTime = 0;
>         int oSleepTime = 10;
>         Thread oStartingThread = null;
> 
>         public InterruptTimer(int aLength, int aSleepTime, Thread
> aStartingThread) {
>             // Both times are in ms
>             oSleepTime = aSleepTime;
>             oEndTime = System.currentTimeMillis() + aLength;
>             oStartingThread = aStartingThread;
>         }
> 
>         public void run() {
>             // Loop until the end time is reached or reset() was called.
>             while (System.currentTimeMillis() < oEndTime) {
>                 try {
>                     Thread.sleep(oSleepTime);
>                 } catch (InterruptedException ex) {
>                 }
>             }
>             if (oEndTime > 0) {
>                 timeout();
>             }
>         }
>         public void reset() {
>             oEndTime = 0;
>         }
> 
>         public void timeout() {
>             System.out.println("**************** stop the request thread");
>             oStartingThread.stop();
>         }
>     }
> }
> 
> [/code]


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org