Compound Theory

v2.0

Categories

  1. Transfer
  2. ColdFusion
  3. JRuby
  4. Java
  5. ColdSpring
  6. Squabble
  7. JavaLoader
  8. ColdDoc
  9. 2ddu
  10. AsyncHTTP
  11. OO Analysis and Design
  12. Flex
  13. Railo
  14. XML / XSL
  15. Hibernate
  16. ColdFusion Builder
  17. Fall
  18. Ubuntu
  19. XHTML / CSS
  20. Eclipse
  21. Git
  22. Oracle Database
  23. Usability / UI Design
  24. webDU
  25. cf.Objective()
  26. LWJGL
  27. cf.Objective(ANZ)
  28. Captcha
  29. MAX
  30. Melbourne CFUG
  31. Martial Arts
  32. Random Things
  33. Conduit

Recent Posts

Projects

Recent Comments

24 September 2007 12:57 PM 9 Comments

How to tell if code is being run inside a CFTHREAD tag

One restriction I ran into today when doing some ColdFusion8 specific performance enhancements to Transfer with <cfthread> is that you can't make a child thread within an already created <cfthread>, so something like:

<cfthread action="run" name="a">
    <cfthread action="run" name="b">
    </cfthread>
</cfthread>

Will end up with lots of errors in your logs saying things like:
Error","cfthread-1","09/24/07","12:03:42",,"A: Thread B cannot be created. Child threads are not supported."

Which is probably not what you actually want, as you would most likely like for you code to actually execute.

I'm not a huge fan of this limitation, but I can kind of understand where the engineers are coming from - they don't want us CF developers to shoot ourselves in the foot with ridiculously spawning multi threaded applications.

So, in my current situation, I wasn't too fussed if I had a whole, brand new thread, but where my code was being run, I was so far down the stack of method calls, I have no way of knowing if the original call had come from a standard ColdFusion thread, or if it had come from a <cfthread> create thread, and both of which were highly possible.  However, if the execution wasn't coming from a <cfthread> created thread, I wanted to execute my code inside a <cfthread> statement, as I didn't care what the results where, and it would be faster for the end user just to have the code run asynchronously.

If that just made your head hurt, I basically have a series of method calls that look like:

A()
 - makes a <cfthread> call, and calls C()

B()
- Does some work...
- Calls C() from the current thread.

C()
- makes a <cfthread> call, and then does some work

This is an over simplification of the process (mine is far more levels deep), but gives you an idea of the trouble I was facing - the method call could go through A() or through B(), and at the level of C() I wasn't aware of whether or not I had started on the base ColdFusion thread or not.

I could have done this passing a parameter all the way down the method chain to tell it if it should fire asynchronously, but that seemed like a lot of extra work, and would have put a level of complexity within the whole process, and any other process that was related to this, that it didn't seem like the appropriate course of action.

So I thought to myself - there has to be a way to find out if the current thread is a regular, ColdFusion thread, or if it is a <cfthread> invoked thread, and funnily enough, skipping into some Java, there is!

The first thing we have to do, is get access to the java.lang.Thread object:

Thread = createObject("java", "java.lang.Thread");

Now, the Thread object, has a great method 'currentThread()', which returns the current thread that the executing code is on:

currentThread = Thread.currentThread();

What is good to know, is that Threads in Java can exist in ThreadGroups, which is a handy way of grouping Threads together for common operations, and other clever things.  The nice thing here, is that ThreadGroups have a method called 'getName()' which returns the name of the ThreadGroup.

Strangely enough, <cfthread> created threads live inside the ThreadGroup named 'cfthread'! So now we can compare this against the name of the current Thread's ThreadGroup

if(currentThread.getThreadGroup().getName() eq "cfthread")
{
  //do something...
}

We can also wrap this up nicely into a quick little UDF:

<cffunction name="amInCFThread" hint="returns 'true' if the current thread is a cfthread, returns false otherwise" access="public"returntype="boolean" output="false">
    <cfscript>
        var Thread = createObject("java","java.lang.Thread");

        if(Thread.currentThread().getThreadGroup().getName() eq "cfthread")
        {
            return true;
        }

        return false;
    </cfscript>
</cffunction>

This function returns 'true' if the currently executing code is inside a <cfthread>, and 'false' if it is not.

So now, in my function C() I can have:

C()
if(amInCFThread())
{
   // run code
}
else
{
  // make <cfthread> and run code.
}

And continue on my merry way!

Pretty handy if I'm not sure if my <cfthread>'d code will end up being run by other ColdFusion created threads or not.