Extending The Current Request Timeout In ColdFusion / CFML

The request timeout determines how long the current request / CFThread can execute before the request throws a timeout exception. For the most part, this value is either never set (which then uses the default timeout defined in the ColdFusion admin); or, it's set once at the top of the request. Sometimes, however, I run into situations where I need to dynamically update the timeout of the current page. Unfortunately, the CFSetting tag doesn't support this; as such, I wanted to outline ways in which this can be hacked into the request in either Adobe ColdFusion or Lucee CFML.

ASIDE: Over on the Lucee Dev Forum, I put out a suggestion that the CFSetting tag add an "extend" attribute to perform this operation. I'm not married to the idea - it was just a thought.

When you use the CFSetting tag to set the timeout for the current request, you're setting an absolute value, not a relative value. Which means, if your request has already been running for 5-seconds, and then you set the request timeout to be 10-seconds, the new timeout threshold for the request will be 10-seconds - not 15 (which would have been 5 + 10).

To see this absolute value in action, we can attempt to increment the timeout value while making CFHttp requests that we know will exceed the defined threshold:

 requestSetTimeout( 5 ); blockForSeconds( 4 ); // CAUTION: !! DOES NOT WORK !! requestSetTimeout( 5 ); blockForSeconds( 4 ); writeOutput( "Done" ); // ------------------------------------------------------------------------------- // // ------------------------------------------------------------------------------- // /** * I set the request timeout to the given seconds using the native CFSetting tag. */ public void function requestSetTimeout( required numeric timeoutInSeconds ) < cfsetting( requestTimeout = timeoutInSeconds ); >/** * I block for the given duration in seconds by using HTTP requests that block for one * second. By performing this blocking in 1-second increments (essentially), this gives * the overall page request more opportunities to step in and throw a timeout. */ public void function blockForSeconds( required numeric durationInSeconds ) < for ( var i = 1 ; i > 

This code might look like I'm increasing the timeout by 5-seconds before I make my long-running requests; but, again, that's not how the CFSetting tag works. As such, when we run this ColdFusion code, we get the following errors (truncated):

Lucee CFML: RequestTimeoutException : request index.cfm has run into a timeout (timeout: 5 seconds) and has been stopped. The thread started 5028ms ago.

Adobe ColdFusion: RequestTimedOutException : The request has exceeded the allowable time limit Tag: cfhttp .

That second call to set the request timeout was, essentially, a no-op since I was setting it from 5 to 5 .

In order to extend the current request timeout, our subsequent calls to the CFSetting tag have to set an increasingly large absolute value. Unfortunately, this isn't obvious; and, there's no single way to do this cross-platform (that I know of). But, it can be finagled in both Lucee CFML and Adobe ColdFusion through the use of the getPageContext() system function.

Here's an updated version of the above approach; but, instead of calling requestSetTimeout() a second time, I'm calling requestExtendTimeout() ! This method attempts to encapsulate the cross-platform complexity.

 requestSetTimeout( 5 ); blockForSeconds( 4 ); // NOTE: I'm EXTENDING here, NOT setting. requestExtendTimeout( 5 ); blockForSeconds( 4 ); writeOutput( "Done" ); // ------------------------------------------------------------------------------- // // ------------------------------------------------------------------------------- // /** * I EXTEND the request timeout by the given seconds using the native CFSettings tag. * * CAUTION: In Lucee CFML, this extends the existing request timeout. In Adobe * ColdFusion, this extends the current execution time of the request. */ public void function requestExtendTimeout( required numeric timeoutInSeconds ) < var pageContext = getPageContext(); var requestTimeout = pageContext?.getRequestTimeout(); // ADOBE COLDFUSION does NOT support request timeout functions in the page // context. As such, we'll have to go a bit more low-level. if ( isNull( requestTimeout ) ) < var startedAt = getPageContext().getFusionContext().getStartTime(); var startedSecondsAgo = now().diff( "s", startedAt ); cfsetting( requestTimeout = ( startedSecondsAgo + timeoutInSeconds ) ); // LUCEE CFML allows request timeouts to be configured on the page context. >else < cfsetting( requestTimeout = ( ( requestTimeout / 1000 ) + timeoutInSeconds ) ); >> // . truncated - other two methods are the same in first example . // 

As you can see, I attempt to call pageContext?.getRequestTimeout() which will fail gracefully on Adobe ColdFusion thanks to the safe navigation operator. I use the result of this call to determine which platform I'm on; and, then, branch into a platform-specific approach for calculating the new request timeout.

And, when we run this in both Lucee CFML and Adobe ColdFusion, we get the following output:

The request timeout was successfully extended to 10-seconds on both CFML platforms, allowing 8-seconds worth of CFHttp calls to execute. I don't love having to reach into the Page Context in order to accomplish our goals here. But, to be fair, I don't have to extend the request timeout very often.

UPDATE: Using the coldfusion.runtime.RequestMonitor Class

Right after I published this article, I came across another article that I wrote in 2007 dealing with the same exact topic. In that article, I use the internal ColdFusion class, coldfusion.runtime.RequestMonitor to get the current request timeout. And, unlike the getPageContext() approach that I used above, this RequestMonitor class appears to work in both Lucee CFML and Adobe ColdFusion.

Here's an updated demo that gets the current request timeout from this Java class:

 requestSetTimeout( 5 ); blockForSeconds( 4 ); // NOTE: I'm EXTENDING here, NOT setting. requestExtendTimeout( 5 ); blockForSeconds( 4 ); writeOutput( "Done" ); // ------------------------------------------------------------------------------- // // ------------------------------------------------------------------------------- // /** * I EXTEND the request timeout by the given seconds using the native CFSettings tag. */ public void function requestExtendTimeout( required numeric timeoutInSeconds ) < // CAUTION: Your ColdFusion platform needs to have permissions to access Java // objects in order to use this (I think). var currentTimeout = createObject( "java", "coldfusion.runtime.RequestMonitor" ) .getRequestTimeout() ; cfsetting( requestTimeout = ( currentTimeout + timeoutInSeconds ) ); >// . truncated - other two methods are the same in first example . // 

This approach is more akin to the approach that I used with Lucee CFML.

Want to use code from this post? Check out the license.

You Might Also Enjoy Some of My Other Posts