What Happens When A ColdFusion CFLock Timeout Is Exceeded Without Error?

Posted February 8, 2010 at 9:25 AM by Ben Nadel

Tags: ColdFusion

Last week, when I was working on my jQuery Photo Tagger plugin (for Flickr-style photo annotation), I was using CFLock to create thread-safe cache updates in the ColdFusion aspect of the code. As I was doing that, it occurred to me - I wasn't 100% sure what would happen if the timeout (indicated by the CFLock tag) was exceeded and no error was thrown? In the CFLock tag, you can use the ThrowOnTimeout attribute to determine the action taken by the thread if the a lock cannot be successfully obtained in the allotted time; but, what would that action actually be? Would the paused thread simply enter the CFLock tag body? Or, would it skip it?

 
 
 
 
 
 
 
 
 
 

I decided to get to the bottom of this by creating two tags that would compete for the same named lock. One thread pauses before the CFLock; one thread pauses whilst inside the CFLock. In this way, they get to it at different times and compete head-to-head for ultimate victory!. Here is the first page (a.cfm) which is the one that will have to wait for the CFLock:

a.cfm

  • A: Before the CFLock tag.<br />
  •  
  •  
  • <!---
  • Pause this thread to make sure the other thread gets
  • to the CFLock first.
  • --->
  • <cfthread
  • action="sleep"
  • duration="750"
  • />
  •  
  • <!---
  • Get an exclusive lock (this named lock is shared with
  • the other thread). Notice that we are asking the page
  • NOT to throw an error if the lock cannot be made within
  • the given timeout.
  • --->
  • <cflock
  • name="cflockTimeoutTest"
  • type="exclusive"
  • timeout="1"
  • throwontimeout="false">
  •  
  • A: Inside the CFLock tag.<br />
  •  
  • </cflock>
  •  
  •  
  • A: After the CFLock tag.

Notice that the CFLock tag specifies that no error should be thrown if the lock cannot be gotten. The second page (b.cfm) gets to the CFLock tag first and then pauses, once inside, for a time that is greater than A's specified timeout:

b.cfm

  • B: Before the CFLock tag.<br />
  •  
  •  
  • <!---
  • Get an exclusive lock (this named lock is shared with
  • the other thread).
  • --->
  • <cflock
  • name="cflockTimeoutTest"
  • type="exclusive"
  • timeout="1">
  •  
  • B: Inside the CFLock tag.<br />
  •  
  • <!---
  • Once inside the tag, let's sleep the thread so that
  • the lock will be held for a while (preventing the other
  • page from entering within the given selected timeout).
  • --->
  • <cfthread
  • action="sleep"
  • duration="#(3 * 1000)#"
  • />
  •  
  • </cflock>
  •  
  •  
  • B: After the CFLock tag.

Notice that this page pauses its lock for 3 seconds, which is greater than the one second timeout specified in page A.

I then put these two pages head-to-head in a Frameset (I won't bother showing the code for that) to see what would happen. When I ran the two pages at the same time, I got the following output from A:

A: Before the CFLock tag.
A: After the CFLock tag.

... and the following output from B:

B: Before the CFLock tag.
B: Inside the CFLock tag.
B: After the CFLock tag.

As you can see, when page A failed to get a lock in the specified timeout, it simply skipped over the CFLock tag altogether. This is good; this is the outcome that I was hoping for (and one that I have coded against) and it's nice to see that it is what actually happens. At least I don't have to go back and fix my code.

So, why would one not want to throw an error if a lock was not obtained? I think this is definitely a rare case, but one that I have used a few times. Typically, I will use this if I am inserting / mutating large amounts of database records containing very non-critical information. In such a case, I might not care if periods of intense performance fail to insert a few rows here and there.

Another place where I actually use this a lot is within a scheduled task. If I have a scheduled task that might take a while to run, I will typically wrap the entire task in a named CFLock tag with a timeout of one second. This way, if the scheduled task tries to execute while the previous instance is still running, the scheduled task will simply skip over itself.

After you've written a bunch of code under a given assumption, it's always a bit scary to realize that you've never tested to confirm the behavior you were expecting. When it comes to CFLock, it's nice to see that when a thread cannot obtain a lock in the given timeout, it skips over the tag altogether.




Reader Comments

Feb 18, 2010 at 11:44 PM // reply »
149 Comments

I'd never thought to use a named lock to guarantee that frequently running scheduled tasks wait for themselves! Genius.

I can't believe that the minimum timeout you can use is 1 second. That's like 10 minutes in Internet years.


Feb 19, 2010 at 2:48 PM // reply »
11,238 Comments

@David,

Thanks my man - it's a method I've found very useful for long running tasks.


Jul 1, 2010 at 5:52 PM // reply »
3 Comments

Why would you NOT want it to execute the code in the CFLOCK tag? If you don't care if it is executed, then don't include the code on the page.

Also, can you explain this to me? "In such a case, I might not care if periods of intense performance fail to insert a few rows here and there."

When would there be an instance when you didn't care if it failed to insert a few rows here and there? That seems to raise a red flag on data integrity.


Aug 1, 2010 at 10:38 PM // reply »
11,238 Comments

@Sdtacoma,

This kind of technique is actually great for scheduled tasks that might hand or potentially overlap in a way that is not appreciated:

http://www.bennadel.com/blog/1844-Making-Sure-Scheduled-Tasks-Don-t-Overlap-In-ColdFusion.htm


Jul 10, 2012 at 3:45 PM // reply »
11 Comments

Question. What would you consider a good standard setting for the timeout value?

We have an issue with a new CF Unix server that is failing load tests constantly (it is configured to the bare minimum specs required in terms of memory, and would take an Act of God to get more memory) and the hardware folks are claiming that our usage of CFLOCK is the issue for the failures.

I am of the opinion that exclusive locks are the only kind needed, that readonly are nice to have but not critical. We have exclusive locks in place anytime an application or session variable is set. We have a 10 second timeout as a default value. They want us to change it to 2-3 seconds. Every CFLOCK will throw an error, btw.

Basically my opinion is that if the server cannot handle needing 10 seconds to acquire a lock, shrinking the value will only make things worse. Also I don't think 10 is an unreasonable value, but I'd like to hear what others think.


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