Ask Ben: Limiting The Amount Of Time A Block Of Code Can Run

Posted April 2, 2007 at 8:10 AM by Ben Nadel

Tags: ColdFusion, Ask Ben

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?

NOTE: Please disregard the solution below! Christoph Schmitz pointed out that this is a serious misunderstanding of how CFLock timeout works... I thought it was how long it could RUN... it is how long it will WAIT. Sorry for misleading anyone. I thought I was helping other people, but it turns out, this time, I get to learn something :)

Please see a better answer here: http://www.bennadel.com/index.cfm?dax=blog:618.view

For starters, we cannot force a piece of code to execute faster than it is going to on its own. If we could do that, I would make sure all my pages executed in 16ms. What we can do, though, is "misuse" the CFLock tag to make sure that your piece of code is only allowed to execute for X number of seconds before it throws an error. We can leverage the TimeOut attribute of the CFLock tag to allow the code a maximum amount of time in which it can run. If the CFLock times out and throws an error, we can then catch it and try to recover from the too-long-running task:

  • <!--- Try to execute the following block of code. --->
  • <cftry>
  •  
  • <!---
  • By putting a named lock on this block of code using
  • a CreateUUID() value, we can make sure it never
  • becomes single-threaded as no two CreateUUID()s are
  • the same. Furthermore, we can limit the amount of
  • time this code ran run by using the TIMEOUT attribute
  • of the CFLock tag.
  • --->
  • <cflock
  • name="#CreateUUID()#"
  • type="READONLY"
  • timeout="5"
  • throwontimeout="true">
  •  
  • <!---
  • 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>
  •  
  • </cflock>
  •  
  •  
  • <!---
  • Catch an errors that get thrown from our
  • CFLock (if it times out).
  • --->
  • <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.
  • --->
  •  
  • </cfcatch>
  •  
  • </cftry>

There are a few things to notice about the CFLock tag:

  1. We are using a named lock, not a scope lock. By using a named lock in conjunction with a CreateUUID() call, we can ensure that this block of code never becomes single threaded. This is good because I assume this page is not single threaded to begin with (so let's not force it to become so).
  2. We are using a timeout of 5 seconds. This gives the black-boxed code a maximum of 5 seconds to run. You can, of course, adjust this to be what you think it should be; however, this value should be smaller than the request time out of the page itself (otherwise, the page may crash anyway).
  3. We are having the CFLock tag throw an error if the time out is exceeded. This is the default value for the CFLock tag, but I put it in to drive the point home. This is key because the whole thing is wrapped in a CFTry / CFCatch block - the thrown error will give us a chance to recover from the long-running code. After all, the whole point of this is to NOT have the page crap out.

I hope this works for you. I would not exactly recommend this technique, though, as locking does come with processing overhead and I am not sure how this page is being used (high traffic?). Furthermore, I believe I read somewhere that repeated calls to CreateUUID() actually start to slow down your machine, but I cannot state that as fact, just hearsay.




Reader Comments

Apr 2, 2007 at 9:37 AM // reply »
26 Comments

Ben,

no offense man, but, you got cflock wrong somehow...

The timeout attribute of cflock specifies the time a request will wait until it aquires a lock, it does NOT specify the time a request within the lock may run. You can have a cflock-timeout of 1 second and still have the request run 100s of seconds.

So if you want the cflock to throw an exception, you need to make the lock exclusive and make the lock name static (make the code block single threaded) and then start a second request. Then this second request will timeout after 5 seconds.

IMHO the easiest way to timeout a request is the <cfsetting requesttimeout="x" /> tag.

Chris


Apr 2, 2007 at 9:41 AM // reply »
11,238 Comments

@Chris,

Oh man... you are totally right! Thanks for clearing that up for me. That is a huge misunderstanding in my mind. I knew it felt very wrong to use CFLock in this fashion - another reason now, it simply doesn't work that way.

Thanks for showing me the light :)


Apr 2, 2007 at 10:08 AM // reply »
11,238 Comments

@Christoph,

Does this look any better:

http://www.bennadel.com/index.cfm?dax=blog:618.view


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 17, 2013 at 7:42 PM
HashKeyCopier - An AngularJS Utility Class For Merging Cached And Live Data
Ben - thanks so much for posting these Angular articles and findings, they've been a huge help towards learning one of the more 'complex' JavaScript frameworks out there (IMO). I have been using Angu ... read »
May 16, 2013 at 5:01 PM
UPDATE: Parsing CSV Data Files In ColdFusion With csvToArray()
Your code was the closest thing I've found to obtaining some direction for converting ISO fields to values that CF can translate properly. Thank you for posting! ... read »
May 15, 2013 at 10:37 PM
Very Simple Pusher And ColdFusion Powered Chat
hi id making plz easy ... read »
May 15, 2013 at 6:07 PM
Making SOAP Web Service Requests With ColdFusion And CFHTTP
Ben, you once again saved my bacon at work. Thank you, thank you, thank you! ... read »
May 15, 2013 at 4:15 PM
What If All User Interface (UI) Data Came In Reports?
@Josh, Thanks! @Ben, I definitely recommend the David West book "Object Thinking" I've been quoting from. It goes deeply into the philosophy and history of OO programming. His breadth ... read »
May 15, 2013 at 11:36 AM
Ask Ben: Print Part Of A Web Page With jQuery
I found this helpfull when you need to keep (refresh) the original parent page after closing the iframe child print dialog (Hoping you're not using a form at this time so it won't submit again): On ... read »
May 14, 2013 at 7:13 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, If there's any books you'd recommend on the subject of domain modelling, I'd love to hear it. I just downloaded the free PDF of "Domain Driven Design Quickly". Figured I'd give it ... read »
May 14, 2013 at 6:57 PM
The UX Of Prototyping: Low-Fidelity Is The New High-Fidelity
@Phillip, I'm not sure I follow what you mean? Are you saying that you looked at the list of widgets provided by the jQuery UI and let that be your style guide? ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools