Ask Ben: Limiting The Amount Of Time A Block Of Code Can Run (Attempt II)
I have this application that uses a black-boxed piece of functionality. 98% of the time, this black-boxed functionality runs very fast as expected. Sometimes though, for reasons I cannot yet debug, this function takes so long that the page times out. Is there a way to make sure that just this block of code only executes for X number of seconds?
Ok, my last attempt at answering this question was a total failure that demonstrated my lack of understanding regarding the CFLock tag. Thankfully, Christoph Schmitz has shown my the light. I have re-attempted an answer using the CFSetting / RequestTimeOut tag and attribute. I am not 100% sure it can be done this way, but testing seems to say that Yes, it can.
<!--- Try to execute the following block of code. --->
<cftry>
<!---
By setting a request time out for this page, we are
forcing it to have a maximum amount of time that it
can run. Since the black-boxed code comes after it,
it will be dominated by this CFSetting.
--->
<cfsetting
requesttimeout="5"
/>
<!---
This is our black-boxed piece of code. Not
sure how it works, but we know that 2% of the
time it runs way longer than it should and
crashes the page.
--->
<p>
This will only be allowed to execute for
a maximum of 5 seconds.
</p>
<!---
Catch an errors that get thrown from our
code exceeding the CFSetting timeout attribute.
--->
<cfcatch>
<!---
Our black-boxed piece of code has run too
long. Use this opprotunity to set default
values so that you might be able to recover
from this timeout.
--->
<!---
Since the rest of the page will take some time
to execute, set a new time out for this request.
--->
<cfsetting
requesttimeout="60"
/>
<!--- Perform recovery code here. --->
</cfcatch>
</cftry>
Hopefully this is better.
Want to use code from this post? Check out the license.
Reader Comments
while this solution would work for a calling template, it won't work within a function. I think what the person is asking is if they can make a CFC method time out after a certain amount of time. Now personally I have no idea how to do this.
Yeah, this seems to be a very difficult task (or something simple that I am just not thinking of). I saw a presentation on Blue Dragon not so long ago and they had a CFThread tag... I wonder if the CFThread tag has a timeout attribute; that seems like something that would do the trick here - wrapping the "locked down" code in a CFThread tag and forcing a small timeout.
When I use "while" loops, I often do something like this:
-----------------------
<!--- Set the time before entering the loop --->
<cfset var timeout = now() />
<cfloop condition="TRUE">
...do something here...
<!--- End the loop if it has run for more than five seconds --->
<cfif dateDiff("s", timeout, now()) GTE 5>
<cfbreak />
</cfif>
</cfloop>
-----------------------
Of course, that won't prevent the processing during an individual iteration of the loop from running more than five seconds.
Just came across this issue ... as there is no timeout property for CFFEED, it's not possible to abort a request e.g. after 5 seconds ... http://cfstuff.blogspot.com/2009/02/cffeed-not-usable-due-to-missing.html
YES YES YES!!! thank you so much for this post!
I was having trouble with a cffeed from an external site which was timing out constantly so getting a horrible error message on my page,
but i stumbled across this solution after lots of googling and now i have it so if my first feed times out then it reads in an alternative feed so no more errors!
I know your post is quite old but its just helped me out so much!
Works great Ben. Simple and sweet. Was something I had been trying to accomplish for a few, sure to add to it eventually.