Looking to run a CFM template asynchronously - aka: run it in the background. Gotchas:
* Must work under MX 6.1
* I can't use an event gateway
* Can't use CFSCHEDULE (unless you know of a way to post data to the URL)
This reminds me of that old Polly-O String Cheese commercial where the guy walks into the pizza parlor and says something like, "Give me a pizza, hold the tomato sauce, hold the crust". What we are trying to do here is run an asynchronous task without all the fixins that make ColdFusion good at this.
Aside from the fact that I am not sure what bullet point #3 means, the only way I can think of doing this is to create a ColdFusion page that calls itself recursively using the CFHttp tag. This has all kinds of pitfalls which make my stomach feel uneasy, but in this sample code I am trying to put in some effect minimizers that stop this idea from totally crashing your machine.
<!--- Set file path. ---> <cfset strPath = ExpandPath( "./log.txt" ) /> <!--- Set safety file path (used at bottom). ---> <cfset strSafetyPath = ExpandPath( "./run.txt" ) /> <!--- Append the file hit. This is where you would normally do your processing, but for our testing purposes, we are just going to log the hit to a file. ---> <cffile action="append" file="#strPath#" output="#TimeFormat( Now(), 'HH:mm:ss.L' )#" addnewline="true" /> <!--- Sleep the thread for a little bit to give the server a break before this starts to demand resources once again. ---> <cfset objThread = CreateObject( "java", "java.lang.Thread" ).CurrentThread() /> <!--- Sleep for 2 seconds. ---> <cfset objThread.Sleep( JavaCast( "long", (2 * 1000) ) ) /> <!--- Before we call the page again, let's put in a check to make sure that we don't run FOREVER. We will only re-call the script if this file exists. ---> <cfif FileExists( strSafetyPath )> <!--- Since this file exists, re-run the page using CFHttp with no wait time (or minimal wait time). If you ever want to kill this file, just delete that file. ---> <cfhttp url="http://#CGI.server_name##CGI.script_name#" method="get" timeout="1" /> <p> Your page has been re-launched in the background. If you want to kill this process, simply delete this file: </p> <cfelse> <p> This file cannot re-run until this file exists: </p> </cfif> <!--- Ouptut safety file. ---> <p> <cfset WriteOutput( strSafetyPath ) /> </p>
First, the help minimize some of the load on the ColdFusion server, I am asking the thread to sleep for 2 seconds before it re-launches itself using CFHttp. The second safety method is that this page will ONLY re-launch itself if the "run.txt" file exists. This file does nothing but server as a boolean flag; this is there so that you can delete or rename the file (run.txt) if you want the original script to stop running. This way, you could reasonably write another page that would conditionally rename the run.txt file based on URL params such that you could create a way to turn this script off using another script.
The caveat here is that you have to launch the first task manually. Once it gets going, though, it takes care of running itself.
Running this script, our log.txt text file ends up looking like this:
This whole thing makes me feel really uneasy. I am putting this out there because it was asked of me, but I really don't like it :) What might be a better methodology is to just build a simple HTML page that makes an AJAX call to the page every X number of minutes. The caveat there is that you need to keep that browser running, but at least it feels much safer to me.
Want to use code from this post? Check out the license.