Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at CFUNITED 2010 (Landsdown, VA) with: David Lund and Ryan Jeffords

Conditionally Exiting Out Of A CFThread Tag In ColdFusion

By Ben Nadel on
Tags: ColdFusion

Yesterday, I was reviewing some code with Josh Siok. The code implemented an asynchronous task executing inside of a CFThread tag in ColdFusion 9.0.1. We had to add some code that would, under certain circumstances, prematurely exit out of the CFThread execution. But, I realized that I had never actually done that before - conditionally exit out of a CFThread tag. At least not that I could remember. As such, I figured it would be worth a quick blog post.

In the following code, I'm simply demonstrating a few ways to exit out of a CFThread tag before that natural termination of the thread body. I determine the execution flow by setting flags pre/post exit and then outputting them:

  • <cfscript>
  •  
  •  
  • thread
  • name = "threadWithExit"
  • action = "run"
  • {
  •  
  • thread.preExit = true;
  • thread.postExit = false;
  •  
  • // Exit thread using exit.
  • exit;
  •  
  • thread.postExit = true;
  •  
  • } // END: Thread.
  •  
  •  
  • // ------------------------------------------------------ //
  • // ------------------------------------------------------ //
  •  
  •  
  • thread
  • name = "threadWithReturn"
  • action = "run"
  • {
  •  
  • thread.preReturn = true;
  • thread.postReturn = false;
  •  
  • // Exit thread using return.
  • return;
  •  
  • thread.postReturn = true;
  •  
  • } // END: Thread.
  •  
  •  
  • // ------------------------------------------------------ //
  • // ------------------------------------------------------ //
  •  
  •  
  • thread
  • name = "threadWithAbort"
  • action = "run"
  • {
  •  
  • thread.preAbort = true;
  • thread.postAbort = false;
  •  
  • // Exit thread using abort.
  • abort;
  •  
  • thread.postAbort = true;
  •  
  • } // END: Thread.
  •  
  •  
  • // ------------------------------------------------------ //
  • // ------------------------------------------------------ //
  •  
  •  
  • // Join the threads so we can examine the thread scope.
  • thread action = "join";
  •  
  • writeOutput( "Thread With Exit - #cfthread.threadWithExit.status# <br />" );
  • writeOutput( "- Pre: #cfthread.threadWithExit.preExit# <br />" );
  • writeOutput( "- Post: #cfthread.threadWithExit.postExit# <br />" );
  • writeOutput( "<br />" );
  •  
  • writeOutput( "Thread With Return - #cfthread.threadWithReturn.status#<br />" );
  • writeOutput( "- Pre: #cfthread.threadWithReturn.preReturn# <br />" );
  • writeOutput( "- Post: #cfthread.threadWithReturn.postReturn# <br />" );
  • writeOutput( "<br />" );
  •  
  • writeOutput( "Thread With Abort - #cfthread.threadWithAbort.status#<br />" );
  • writeOutput( "- Pre: #cfthread.threadWithAbort.preAbort# <br />" );
  • writeOutput( "- Post: #cfthread.threadWithAbort.postAbort# <br />" );
  • writeOutput( "<br />" );
  •  
  •  
  • </cfscript>

As you can see, I am using the CFExit, CFReturn, and CFAbort tags to attempt conditional exiting of the CFThread tag body. And, when we run the above code, we get the following output:

Thread With Exit - COMPLETED
- Pre: true
- Post: false

Thread With Return - COMPLETED
- Pre: true
- Post: false

Thread With Abort - TERMINATED
- Pre: true
- Post: false

As you can see, none of the "post" flags were turned on. This indicates that CFExit, CFReturn, and CFAbort can be used to conditionally exit out of a CFThread tag body.

At first, I was unsure about CFExit since I've only ever used that in the context of standard CFM templates and ColdFusion custom tags. I wasn't sure if the CFExit in the thread context would exit out of thread only, or exit out of the parent template.

The use of CFReturn is a fun one. This works because CFThread runs as a function under the hood. Maybe I'm a whack-job, but for some reason, using the CFReturn tag feels a bit more natural than using the CFExit tag. Perhaps that's because I'm so used to everything executing inside CFFunction blogs these days.

The CFAbort tag works, but it's more like a brute-force approach. Notice that the "status" of the CFThread using the CFAbort is "Terminated", not "Completed."

Not much more to say about that. Basically, you can use CFExit, CFReturn, or CFAbort to create guard-statements for your CFThread tags.




Reader Comments

Good article. In web programming(asp.net jsp, php,coldfusion) I always thought that working with explicit threads hard to trace and can be lead to headaches. As a programming, you are good at it but as a system admin, how do you trace them? Which tool do you advice to apply when we think there are some threads slowing down the coldfusion server?

  • <CFBen na="true" del="yes" />

Reply to this Comment

@Soncu,

Excellent question - debugging threads can be a difficult task. One thing that I have been enjoying lately is the "Fusion Reactor" server-monitoring product:

http://www.fusion-reactor.com/fr/

It allows you to examine all the requests running on the server, including JDBC connections and stack traces. In the stack trace, you can see what your CFThreads are doing as well. It's pretty sweet. I actually just got to the bottom of a bottle neck on the server by looking at the stack traces and seeing that all of our threads were being tired up in a single point in the system.

Outside of things like that, though, I will often wrap the body of my CFThread in a try/catch and put some logging in the catch statement. Something like (pseudo code):

  • thread {
  •  
  • try {
  •  
  • // .... your async logic here ....
  •  
  • } catch ( any error ) {
  •  
  • logger.error( error );
  •  
  • }
  •  
  • }

That way, if the thread fails, at least I can see it in our error logs.

Reply to this Comment

Post A Comment

?
You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
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.