multithreadingcoldfusioncfthread

Check on coldfusion threads


I am trying to do the following, and it's not throwing an error, but I can't tell if it's doing anything either. Is there a way to check a thread status in Coldfusion?

<cfset start = CreateDate(2005, 1, 1) />
<cfset stop = DateAdd("m", 1, now() ) />

<cfloop condition="start LTE stop">

    <cfthread name="#dateformat(start, 'mmddyyyy')#" action="run"> 

            <cfinvoke component="CFCs.DoSomething" method="DoSomething" 
                returnvariable="success" 
                dateStartDate="#dateformat(start, 'mm/dd/yyyy')#"
                dateEndDate="#dateformat(DateAdd('m', 1, start), 'mm/dd/yyyy')#"
                 />


    </cfthread> 

   <cfoutput> #LSDateFormat(start)# <br/> </cfoutput>


   <cfset start = DateAdd("m", 1, start)>

</cfloop>

Solution

  • First, your start variable in your thread can change since it is not being passed in. Anything that you need inside your thread scope should be passed in the attributes. This makes the variable thread-safe. Otherwise if the variable changes outside the thread, it changes inside the thread as well and can produce unexpected results. Inside your thread, you can store variables in the THREAD scope if you want to access them outside your thread. You aslo can put your code in a try/catch and store the exception in the THREAD scope so you can read it outside your thread to determine if it errored and why.

    Keep a list of thread names and then use <cfthread action="join"> after your loop. This tells CF to wait until all threads have finished. You can then access the threads via the CFTHREAD scope. The CFTHREAD structure will store your threads with a key of the thread name, so you can just loop over it.

    <cfset start = CreateDate(2005, 1, 1) />
    <cfset stop = DateAdd("m", 1, now() ) />
    <cfset threadNames = ''>
    
    <cfloop condition="start LTE stop">
        <cfset newThreadName = dateformat(start, 'mmddyyyy') >
        <!--- add thread name to list of threads --->
        <cfset threadNames = listAppend(threadNames, newThreadName ) >
    
        <cfthread name="#newThreadName#" action="run" start="#start#">
            <cftry>
                <!--- store a variable in THREAD scope to be used outside thread --->
                <cfset THREAD.start = ATTRIBUTES.start>
                <cfset THREAD.foo = "bar">
    
                <!--- Do stuff here --->
    
                <cfcatch type="any">
                    <!--- catch any error and store in the thread result --->
                    <cfset THREAD.exception = CFCATCH>
                </cfcatch>
            </cftry>
    
    
    
        </cfthread>
    
       <cfoutput> #LSDateFormat(start)# <br/> </cfoutput>
    
    
       <cfset start = DateAdd("m", 1, start)>
    
    </cfloop>
    
    <!--- this waits for all threads to complete --->    
    <cfthread action="join" name="#threadNames#" />
    
    <!--- loop over thread results --->
    <cfloop collection="#CFTHREAD#" item="t">
        <!--- do whatever you want with the thread result struct --->
        <cfoutput>#CFTHREAD[t].STATUS# <br /></cfoutput>
    </cfloop>
    
    <!--- Dump all the threads --->
    <cfdump var="#CFTHREAD#" abort="true" />