ColdFusion CFThread Tag Body Executes As A Function Call

Posted February 23, 2010 at 8:44 AM by Ben Nadel

Tags: ColdFusion

A few years ago at CFUNITED, I was talking to Rupesh Kumar about the new CFThread features he built into ColdFusion 8. In the conversation (which may have been a presentation), Rupesh mentioned that the CFThread tag body actually executes as a function call. At the time, I didn't put much thought into that; but, with ColdFusion 9's new implicit LOCAL scope for function execution, I thought it might be time to play around a bit.

After trying a few CFDump and CFSet calls, I was quickly able to confirm that CFThread does, in fact, execute as a function call, complete with an arguments scope and the implicit local scope. Here is the test code that I ran:

  • <!--- Launch a parallel thread. --->
  • <cfthread
  • name="localTest"
  • action="run"
  • girl="Tricia">
  •  
  • <!---
  • The GIRL attribute is actually passed as part of the
  • Attributes collection.
  • --->
  • <cfset thread.attributesGirl = attributes.girl />
  •  
  • <!---
  • The Attributes collection is actually passed as an
  • argument to this thread Function. As such, we can access
  • it via the arguments.
  • --->
  • <cfset thread.argumentsGirl = arguments.attributes.girl />
  •  
  • <!---
  • Both the attributes are arguments are actually part of
  • the implicit LOCAL scope now part of the ColdFusion
  • scope collection.
  • --->
  • <cfset thread.localGirl = local.attributes.girl />
  •  
  • <!---
  • Because this is actually a function call, we can use
  • the new CF9 function to get the hidden name of the
  • thread function.
  • --->
  • <cfset thread.calledName = getFunctionCalledName() />
  •  
  • </cfthread>
  •  
  •  
  • <!--- Join the thread so we can examine it. --->
  • <cfthread action="join" />
  •  
  •  
  • <!--- Output the thread object. --->
  • <cfdump
  • var="#cfthread.localTest#"
  • label="Thread Local"
  • />

As you can see, I am testing the existence and functionality of the attributes scope, arguments scope, and local scope as well as the use of ColdFusion 9's new method, getFunctionCalledName(). When running the code above and rejoining the thread, we get the following CFDump output (I have hidden the irrelevant properties):

 
 
 
 
 
 
ColdFusion's CFThread Tag Body Executes As A Function Call. 
 
 
 

As you can see, I was able to access the name, "Tricia," using the attributes, arguments, and local scopes.

This seems like one of this things that is interesting, but entirely not useful in any practical sense. Even knowing this, I don't think there is any way in which I would change the way I currently code my CFThread tags. Even the use of the local scope appears to be unnecessary - non-scoped values are automatically placed into the implicit local scope whether or not the VAR keyword is used during variable definition. Actually, that's probably the most interesting part of this exploration - in a standard function, non-var'd variables are placed, by default, into the page's Variables scope, not the function local scope; so, in this respect, CFThread functions behave different that standard ColdFusion functions.




Reader Comments

Feb 23, 2010 at 1:19 PM // reply »
66 Comments

Makes sense -- multithreading in most operating system-level programming languages (C, Perl, etc) is generally done with functions:

Perl: new Thread \&subroutine;
C++ with pthreads: pthread_create(info, attr, function, funargs);

Some languages want you to create an entirely new class just for the thread. Java's built-in threading (java.lang.thread) is one example of this, as are Python and the Boost library for C++.

Java:
class MyThread extends Thread { ... }
MyThread thread = new MyThread(args);
thread.start();

You can see from the Java example, even though it's an entire class, you still pass in arguments just like you would a regular function (albeit in the ctor).

But ... to get around the fact that you can write non-OO CF code and still use threads, I'd imagine that the internals for cfthread work like so:

1. Parser/compiler sees a cfthread and:
a. Silently bundles it inside a function wrapper, with arguments for the current page context, etc.
b. Inserts a stub class that takes, as an argument, the unique name of the wrapped function. This stub class extends Thread or implements Runnable (another way to do threads in Java, but very similar).
2. The JVM hits the stub class and runs it as a thread, which in turn calls out to the wrapped CF code, giving it a page context, etc. This stub could also be the watchdog function that will kill a thread if it hits its timeout, or if you pause or stop the thread, etc.

It's total speculation, and they could have gone in an entirely different direction, but that's how it works in my head.


Feb 23, 2010 at 1:34 PM // reply »
10,640 Comments

@Rick,

Sounds cool - you have a much more diverse programming background that me, so I will just take that as fact. The one thing that seems to be special about the Thread functions is that the "non-scoped" default memory space is the Local scope, where as in the rest of ColdFusion, it is the Variables scope. Unless, of course, they are some how invoking the method with the "local" scope being its bound-scope as well.

I am not sure how the thread has access to the Variables scope, however; it is not being passed as part of the arguments collection. The whole binding behind threads is very fascinating.


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
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Feb 12, 2012 at 3:37 AM
Learning ColdFusion 8: CFImage Part III - Watermarks And Transparency
Hi Ben, Just to ask currently it is placed bottom right corner, if i need to replace the same rendered image on the bottom left side or in the bottom center, how that can be calculated. bottom ce ... read »
Feb 11, 2012 at 9:29 PM
Use jQuery's SlideDown() With Fixed-Width Elements To Prevent Jumping
I can't say how glad I am that I found your post. Thank you very much. ... read »
Feb 10, 2012 at 7:21 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
Update! Instead of $(eval(options.insertAfter)).after(data['insertData']); I now use: var ajaxNode = document.createElement('span'); var parent = $(eval(options.insertAfter))[0].parentNode; ... read »
Feb 10, 2012 at 6:18 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
encountered this same, what I consider, jQuery bug last week. I'm building a site in which I load some content via AJAX. This content contains Linkedin share button placeholders which Linkedin API ne ... read »
Feb 10, 2012 at 11:30 AM
Cross-Origin Resource Sharing (CORS) AJAX Requests Between jQuery And Node.js
After you understand the concepts here, this is an awesome cheatsheet for enabling CORS in just about anything http://enable-cors.org/ ... read »
JM
Feb 10, 2012 at 9:10 AM
My Safari Browser SQLite Database Hello World Example
@Amy, Here is a very good tutorial on how to use JOIN: http://www.sqltutorial.org/sqljoin-innerjoin.aspx ... read »
Feb 10, 2012 at 4:42 AM
Building A Twitter-Inspired RESTful API Architecture In ColdFusion
This is great, very useful Ben. I spotted a small typo in the api.cgm listing: <cfthrow type="Unauthroized" /> Cheers Stefan ... read »
Feb 9, 2012 at 10:35 PM
CFDirectory Filtering Uses Pipe Character For Multiple Filters (Thanks Steve Withington)
I was wondering if there would be a filter you could apply so that you got everything but what you included in the filter. As in show me all docs that are not a .pdf. ... read »