That title probably doesn't make a lot of sense. What I mean by that is that when you use a CFSetting tag and set the RequestTimeOut attribute, the value you assign does not just apply to everything going forward - it applies to everything going forward in the context of everything that has already happened. Ok, maybe that doesn't clear anything up. What I mean to say is that the RequestTimeOut attribute does not determine the amount of time left, it determines the amount of processing time allowed in total.
Here is a demo to help explain what I am saying. For this example, I use a ColdFusion user defined function named KillTime(). This function simply runs a loop until a given amount of time has passed:
<cffunction name="KillTime" access="public" returntype="void" output="false" hint="I kill time for the given miliseconds."> <!--- Define arguments. ---> <cfargument name="MS" type="numeric" required="true" /> <!--- Get start and end tick out values. ---> <cfset var intStart = GetTickCount() /> <cfset var intEnd = (intStart + ARGUMENTS.MS ) /> <!--- Loop until this time is killed. ---> <cfloop condition="(GetTickCount() LT intEnd)"> <!--- Just try to kill some processing time. ---> <cfset intStart = (intStart * Pi()) /> </cfloop> <!--- Return out. ---> <cfreturn /> </cffunction>
Now, with that function in mind, here is the test code:
<!--- Set the current time out to be 3 seconds. ---> <cfsetting requesttimeout="3" /> <!--- Get the millisecond start time for page processing (so that later on, we can check to see how long the page ran overall). ---> <cfset intStart = GetTickCount() /> <!--- Try to kill some time. ---> <cftry> <!--- Here, we are killing time - 4 seconds to be approximate. This will exceed the request time out set above (3 seconds) and will throw an error. ---> <cfset KillTime( 4000 ) /> <!--- The KillTime() method call has timed out. ---> <cfcatch> First Timeout!<br /> <!--- In an attempt to "recover" from this time out, update the request time out to be six seconds. ---> <cfsetting requesttimeout="6" /> <!--- Try to kill some more time. ---> <cftry> <!--- We are going to try and kill about four seconds. If this is in terms of the six-second timeout set above, this should NOT timeout. However, if this is in the context of the overall page time (including previous kill time calls), then this will timeout. ---> <cfset KillTime( 4000 ) /> <!--- The KillTime() method has timed out. ---> <cfcatch> Second Timeout!<br /> </cfcatch> </cftry> </cfcatch> </cftry> Total Time: #(GetTickCount() - intStart)#
That gives us the following output:
Total Time: 6016
Now, if you look at the code, and the output, you will see that both calls to KillTime() threw timeout exceptions. The first one is straight forward - we tried to kill 4 seconds when the current request timeout only allowed 3 seconds. But, then we set the request timeout to be 6 seconds. In this second KillTime() request, we try to kill 4 seconds. If the previous 6 second timeout was a NEW timer, then this would not timeout (4 is less than 6). However, this second KillTime() method times out. This shows us that request timeout settings don't "add" time, they merely update how much total time is allowed.
Aside from the fact that this gives us a little more insight into using multiple CFSetting tags (which might not be totally obvious - it wasn't to me), it also proves that when a tag or block of code throws a request timeout exception, ColdFusion doesn't die right away - there is some wiggle room in which to recover or potentially add more execution time.
Want to use code from this post? Check out the license.