Asynchronous CFML without a Gateway
I came up with this while coming up with the wrong answer to a different question. My hope is that it is the wrong answer to someone else's question
How do you run an asynchronous request for without having access to a Asynchronous CFML Gateway?
- Encapsulate the code to be run asynchronously into a CFFunction.
- Set the access for the function to "Remote"
- Put the function in a cfc.
- (Optional) Secure the method so that it is called only from server the code resides on.
- Call the code as a webservice using CFinvoke, with a timeout of "1".
- Wrap the code in a cftry block.
- In the cfcatch add the code block below.
- That should do it.
<cfif not FindNoCase("Read timed out", cfcatch.Detail)>
<cfrethrow />
</cfif>
The CFcatch will prevent timeouts from being perceived as errors. The rethrow will ensure that other errors get treated as such.
Now there are some limitations to this. The process will take a minimum of 1 second. Which is slower than using the gateway method, but beats having to pay for the Enterprise version. Granted you don't have a separate application and session scope like you do with the Gateway, but you can if you put the CFC in a subfolder with its own application.cfc or application.cfm. You also don't get information back from the call, but neither do you with a CFML gateway.
Hopefully, this can be of use to someone.
Comments
in essence it's the fact that a webservice is called that makes it asyncronous?
thanx for the tip
Why would you use a gateway to process SQL queries or dump a large amount of data into a database? You can create jobs with SQL server (I don't know what the equivalent is in other databases) to do this. Not only is it supported nativly inside SQL Server, it's much much faster than anything CF can do.
Why would you use CF to send out thousands of emails through a gateway? Again, this is another task that could easily be offloaded to mass email program running on a different server.
It goes with that old saying that just because you can do something, doesn't mean you should. In my opinion CF should be used for one thing, processing web requests. There's no reason to add more load to your CF server by making do task that are outside of the norm when more efficient solutions already exist.
Barry: Imagine that you have a code section that takes 30 seconds. By setting the timeout on the invoke to 1 second, the request will throw an error 1 second. The try block ensures that the error will be caught, but the request will still run. Since the minimum timeout for a weservice call is 1 second that's the least time it will take for the error to be triggered. 


Posted by: Nick Kwiatkowski at July 5, 2006 6:11 PM