CFSetting RequestTimeout Updates Timeouts, It Does Not Set Them

Posted April 4, 2007 at 3:42 PM

Tags: ColdFusion

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:

 Launch code in new window » Download code as text file »

  • <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:

 Launch code in new window » Download code as text file »

  • <!--- 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:

First Timeout!
Second Timeout!
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.

Download Code Snippet ZIP File

Post Comment  |  Ask Ben  |  Permalink  |  Other Searches  |  Print Page




Learning ColdFusion 9 - ColdFusion 9 tutorials, samples, examples, demos

Reader Comments

Apr 4, 2007 at 4:51 PM // reply »
19 Comments

This would make sense, Ben, as ColdFusion uses output buffering by default, and you must explicitly tell it to flush the contents of the buffer. This is unlike language like PHP, for example, which flush content out as it is processed, and you must explicitly tell it to buffer output if you wish for that behavior.


Apr 4, 2007 at 4:55 PM // reply »
6,516 Comments

@Adam,

While I agree with you on the buffering feature, I am not sure how buffering relates the page timeout?


Apr 4, 2007 at 5:52 PM // reply »
26 Comments

good to know, Ben. Thanks!


Apr 4, 2007 at 8:21 PM // reply »
19 Comments

I cannot say with any authority, however I have spent a little time writing my own language interpreters, and found that when assembling my page into my output buffer anytime I found a command that would modify program execution settings, I would put those into my script's environment settings, and overwrite any existing value.

That is essentially what I figure ColdFusion is doing. This is a setting that affects this request's processing environment, and it isn't "queuing" them up, but simply storing the last value.

Once again, no authority, just assumtions based off behavior and my own code in the past. *shrug*


Apr 4, 2007 at 10:22 PM // reply »
97 Comments

What happens if you remove the second requesttimeout setting? Since you've already caught the exception and handled it, how much more wiggle room does CF allow you?


Apr 5, 2007 at 7:40 AM // reply »
6,516 Comments

If I take out the second CFSetting, this is the output:

First Timeout!
Second Timeout!
Total Time: 3031

Looks like the second KillTime() method times out immediately, is caught, and then lets the rest of the page process (which only takes a few milliseconds).

In my experience, the "wiggle room" is generally NOT enough time to do anything much like send an email that has much of any processing time to it (ex. CFDump var="CGI").


Apr 5, 2007 at 7:40 AM // reply »
6,516 Comments

@Adam,

Ahhh, I see what you are saying now. Thanks for the clarification.


Apr 5, 2007 at 9:41 AM // reply »
64 Comments

This is an interesting piece of code.

I would have expected that setting to tell the CF server how long to wait until pulling the plug on the request (kind of what it says on the box). I would not expect it to throw a catchable exception, because it should have ceased processing the request completely.

Good to know, in an esoteric sort of way. Good work.

--
Adam


May 9, 2007 at 5:10 AM // reply »
1 Comments

<code>
<cfset thread = createObject("java", "java.lang.Thread") />
<cfset thread.sleep(5000) />
</code>


Dec 7, 2007 at 11:53 AM // reply »
1 Comments

If what you are suggesting is that the second killtime() still dies because the original requesttimeout (3 seconds) has ended and therefore the second requesttimeout (6 seconds) won't be able to update any remaining time, why does making the second timeout 60 seconds rather than 6 work (not timeout) the second killtime()?


Post Comment  |  Ask Ben

Recent Blog Comments
Nov 21, 2009 at 6:47 PM
Hal Helms - Real World Object Oriented Development, Sarasota - Day Five
@charlie griefer, Thank you.. ... read »
Nov 21, 2009 at 5:15 PM
Using ColdFusion Structures To Remove Duplicate List Values
@Jose Galdamez, Oh heh yeah I didn't paste the whole code. I should have defined the vars -- my bad. It's fixed thou. Thanks. ... read »
Nov 21, 2009 at 4:49 PM
Styling The ColdFusion 8 WriteToBrowser CFImage Output
Great work yet again Ben! Whilst I didn't use this whole code, I copied some of your regex code for a similar problem with the lack of an alt attribute and unescaped ampersands in CFIMAGE for Railo 3 ... read »
Nov 21, 2009 at 1:13 PM
My First ColdFusion Builder Extension - Encrypting And Decrypting CFM / CFC Files
@Ben, Because I am pedantic, I just want to make sure that everyone knows there is absolutely no encryption going on. There is only encoding and obfuscation. The cfencode tool only obfuscates your C ... read »
Nov 21, 2009 at 12:28 PM
Using ColdFusion Structures To Remove Duplicate List Values
@Jody I can't seem to get your code sample to work. If you are still having problems, try this code out and see if it gets you what you wanted. <!--- Comma delimited list with various duplicates ... read »
Nov 21, 2009 at 11:03 AM
Groovy Operator Overloading Does Not Work In The ColdFusion Context
Hi Ben, Thanks for this informative post. Now I am reading ur old posts too ... read »
Nov 21, 2009 at 10:56 AM
HostMySite.com Has The Best ColdFusion Hosting
@Mehul, Yes very nice people, however several downtimes per day which was not acceptable. Hence we had to move out. I am glad you are having good luck with them so far. ... read »