[Looking for Charlie's main web site?]

New for CF9 (and 9.0.1): a query timeout that really works, with a caveat

This is a very interesting change in CF9 (and 9.0.1), which has slipped under the radar for the most part as far as I can tell.

Did you know there is now a setting in the DSN page of the CF Admin (for most DB drivers) that allows you to set a maximum timeout for queries against that DSN? It's a new feature enabled for the DataDirect drivers udpated in CF 9. The caveat? It is ONLY settable there, not in CFQUERY itself, which is a shame (the existing TIMEOUT attribute is not the same and generally does not work). Still, the value of this even at the DSN level is too important to ignore for some challenges. More on that (and some other thoughts) in a moment.

As for the setting, it's in the "Advanced Settings" section for a DSN in the CF 9 Admin, and it's called "Query Timeout". This should not to be confused with the older settings, "Timeout" (which is about inactive connections) or "Login Timeout" (which is about logging in to the connection). The screenshot at right shows all 3. (This blog entry continues, with more information below it.)

I've run a test, and it really does do the job, which is huge. Why? Because it's been a long-time issue that if a CFQUERY got hung up waiting for a response, that request thread (doing the CFQUERY) is then hung until the query finishes, which can sometimes be many minutes, or even hours or days, due to some odd situations. More important, a thread waiting for a query with no timeout can't be terminated (by the JVM, or CF, or the monitoring tools) because the thread was in a native thread state.

With this new option specified, if the request exceeds the timeout, the request does now fail, with a JDBC error, "Execution timeout expired." The same test does NOT timeout with the older cfquery TIMEOUT attribute.

Here are some other notes on the new feature:

  • It works with most of the database drivers. I have confirmed that the setting appears in the DSN settings page for SQL Server, Oracle, MySQL (datadirect), DB2, Informix, Sybase) in CF 9 Enterprise, and in both SQL Server and MySQL (Datadirect) on CF 9 Standard.
  • The timeout's specified in seconds.
  • You can learn more in the CF Admin guide, in this specific page.
  • Oddly, the Admin manual page above only references this new setting in that CF Admin manual is in the the MySQL settings, but again it does appear in all the drivers above.
  • The manual page does even reference the other DBMSs by name in its naming the methods of the Admin API (for other DBMSs) which you can use as well, which can be used to set this default setting in the DSN programmatically.
  • That said, again there is sadly no new QueryTimeout (or QTimeout) attribute for CFQUERY, so for now we can only set this at the datasource level, not per query.
  • I've raised the concerns above on the CF Admin livedocs page (or whatever we are to call it now.)
  • If you look under the covers (in [cf]\lib\neo-datasource.xml), there is in fact a querytimeout connectionstring that this setting controls. If only there was a way we could pass connectionstring values to the CFQUERY, we'd be golden. Some may recall use used to have just such an attribute (ConnectString), but sadly it was deprecated in CF 6. I did try it, to no avail.
  • I will raise have raised a bug with Adobe to get a new attribute for CFQUERY related to this. When I do that, I'll report it here. It's bug 83592. Please add your vote of support for it.
  • There's another page on this Admin setting, in the CF Dev Guide, for those who may be interested in following any other possible places where this feature may be discussed (in the comments there).
  • If you want some code to use to test a request waiting a long time for the DB to return, most databases offer a statement that tells the DB to wait for some time. In SQL Server, that's WAITFOR DELAY 'hrs:mins:secs'. Just use that in a CFQUERY, assuming your DSN definition doesn't limit what SQL statements you can use, in the 'Allowed SQL' section of the Adcanced Settings page.

Why is this setting important?

I think this is a very important setting, and though it has been a hidden gem, it seems, it's one that people should consider. That's why I've flagged this in my CF911 category.

If you're suffering situations where requests are hanging due to long-running queries, and you have not been able to solve the real root cause for why they are hanging (which I always recommend first and foremost), then at least this option can help avoid a situation where queries can run without time limit. An Admin can decide that no queries should be allowed to run more than x seconds.

With that power comes responsibility, of course, and caution. You wouldn't want to preclude someone being able to run a query that really needed to take a long time. That's why it's really better if this was settable on a per-query basis. (And no, the CF page timeout settings are NOT the solution here, because again as I said above, they cannot timeout some kinds of long-running tags, like CFQUERY, CFHTTP, CFINVOKE of a web service, etc.)

What one could do, though (for now), is create different DSNs, where one could be used for most query processing, and another could be used for long-running requests. Yes, it's ok to have 2 DSNs point to the same DB. This same technique has been used when wanting to have most queries run against one DSN with a limited set of "allowed SQL" (per the DSN advanced settings) while another DSN has unfettered SQL access.

Hope this is helpful to some. Let me know what you think, whether this was helpful or if you feel I left something out. Especially please let me know if you may know of a way that we can indeed pass querystring values on a per-query basis.

I'll be speaking at CFinNC, doing "Hidden Gems in CFBuilder"

CFinNC - Carolina ColdFusion / Flex / Air Conference - Oct 17-18, 2009For those attending the awesome free CFInNC conference this coming weekend in Raleigh NC, I'll be speaking on "Hidden Gems in CFBuilder". See the description there for more.

I mentioned last week that I was starting my "Hidden Gems in CF9" series of blog entries, and I'll eventually do a class based on that. In the meantime, I will also soon start sharing some of these CFBuilder hidden gems here as well.

So if you're coming to CFinNC, please look me up and say hello. And if you're not yet planning to attend but live within a few hours driving distance (I'll be driving the 5 hours from Atlanta), you should definitely consider it. There will ba a lot of great speakers and content, as well as community and festivities, all for free.

Help spread the word, online or by grabbing a flyer to put up at your workplace. It's not too late!

Hidden Gem in CF9: controlling Application.cfm/cfc lookup order

It's that time again, time for me to start sharing hidden gems in CF9. In this first offering, I'll point out an interesting option now available in the CF Admin that lets you control how far up the drive CF searches for Application.cfm/cfc files. It's not quite as obvious as it seems, nor is it well documented. One of the options may even surprise you. More on the feature in a moment.

About the hidden gems series

With CF9 out and final, I'm excited to start identifying the interesting little bits and bobs which you may not have heard much about. Some will know I've done this going back to one of my first articles in the CFDJ from Feb 2000, on "Hidden Gems in 4.01".

Over the course of the next few weeks, I'll share various things that you may have missed, whether in the CF Admin, the language, the docs, or otherwise.

Hidden Gem 1: Controlling Application.cfm/cfc Lookup Order in Admin

If you've not noticed it, there is now a setting in the CF9 Admin for controlling how far above the current directory CF will look for Application.cfm/cfc if not found in the current directory. This is a server-wide setting (found on the Settings page).

How application file searching works by default

As you should know, if CF doesn't find an Application.cfm (or Application.cfc, since CF 7) in the current folder where a request starts, CF searches up to the parent, then the grandparent, trying to find one (and since CF 7 if it finds an Application.cfc it chooses that over an Application.cfm).

What many don't know is that by default ColdFusion has always searched all the way to the system root (the drive root). It doesn't stop at the webroot, which could lead to both security and possibly performance issues. This can now be changed using this setting.

To change this, find the Settings page which is the first link in the options on the left (see the arrow pointing to it in the image above). This new setting is about 2/3 the way down this page of settings (which is getting quite long!)

The options available in CF9

As the screenshot above shows, you can now change things to choose either of these alternative search behaviors:

  • Default order
  • Until webroot
  • In webroot

As I said at the outset, things are not quite as obvious as they may seem. OK, the first is: it maintains the default behavior of searching to the system root, such as c:\.

The second does what some have wished: makes CF stop searching when it reaches the webroot. (The third option may make you think that this second option means search until the webroot but do not search in the webroot. That's NOT what it means.)

Before explaining that, let me point out as well that changing this setting is immediate. No restart of CF 9 is required.

The surprising "in webroot" option

So what then is the deal with the third option, "in webroot"? It may surprise you (as it did me, at first). What it does is tell CF to search either in the current directory (as they all do) or if not found, search ONLY in the webroot. It DOES NOT search the directories between the current directory and the webroot. Interesting. (To be clear, it does not mean "don't look in the current directory but only in the webroot". It still takes affect only if there is no Application.cfc/cfm in the current directory where a request starts.)

Why might one use this third option? Well, if they know that their server code directories are setup in such a way that the Application.cfc/cfm file is either in the directory of templates it should apply to, or if not there it's only in the webroot, then this option would suit them.

I can see it potentially causing confusion if folks don't know about the change in behavior and wonder, "why isn't my Application.cfc/cfm file (in an intermediary directory) running?"

Also, the fact that this is a system-wide feature means that all your apps on your entire server must accept the behavior specified here.

No documentation on this feature

Another source of confusion is the fact that there's no documentation explaining this feature. It's mentioned only in passing in the online help of the Administrator, without explanation of the meaning of the options. It's not mentioned at all in the docs, either the "Configuring and Administrating CF" manual or the "Developing Applications" manual. That's a real shame and I hope it will change in the next release.

In the meantime, I hope that this entry will help. Sorry that it was a long one, but again it's just not a trivial feature. It is indeed a hidden gem, and look for more to come from me soon.

(I've provided a zip here that can help you demonstrate things. Unzip it into a web root and run the nested /testdir/testsubdir/test.cfm, and observe that whichever Application.cfm runs reports where it was found. You can rename the various Application.cfm files to xApplication.cfm to observe the impact of CF's search order, and as you change the Admin settings. You'll also want to copy one of the Application.cfm files to a direcory above your webroot to test that, too. The content is identical in all of them.

Of course, beware when unzipping the file that you don't overwrite any Application.cfm that you already have in your webroot. Also, beware that if you have an Application.cfc file in that webroot, it would take precedence over the Application.cfm file.

Finally, to find the zip file, see the link appearing just below this blog entry.)

BlogCFC was created by Raymond Camden. This blog is running version 5.005.

Managed Hosting Services provided by
Managed Dedicated Hosting