Skip to content

Instantly share code, notes, and snippets.

@bennadel
Created January 31, 2014 13:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bennadel/8732182 to your computer and use it in GitHub Desktop.
Save bennadel/8732182 to your computer and use it in GitHub Desktop.
Spawning Nested ColdFusion Threads With Synchronous Fallbacks
<cfscript>
// Create our logger.
logger = new Logger( expandPath( "./log.txt" ) );
// Now, let's try to log serval message from both the currently
// executing page as well as from asynchronous threads.
logger.logMessage( "In parent page 1." );
thread
name = "async1"
action = "run"
{
logger.logMessage ( "In thread 1." );
}
thread
name = "async2"
action = "run"
{
logger.logMessage ( "In thread 2." );
}
logger.logMessage( "In parent page 2." );
</cfscript>
<cfscript>
component
output = false
hint = "I log message to the given text file."
{
// I initialize the logger to log to the given file.
public any function init( required string aFilePath ) {
filepath = aFilePath;
return( this );
}
// ---
// PUBLIC METHODS.
// ---
// I log the given message.
public void function logMessage( required string newMessage ) {
// ColdFUsion has a limit in that threads cannot spawn other
// threads. As such, if we try to run this code asynchronously,
// it's possible that it will fail, if the calling context is
// already inside of a thread. As such, we can TRY to call the
// code asynchronously; and, if it fails due to a nested-thread
// error (the only possible point of failure), we can fall back
// to executing the logging synchronously.
try {
logMessageAsync( newMessage );
} catch ( any error ) {
logMessageSync( "... Asynchronous logging failed." );
logMessageSync( newMessage );
}
}
// ---
// PRIVATE METHODS.
// ---
// I execute the logging ASYNCHRONOUSLY.
private void function logMessageAsync( required string newMessage ) {
thread
name = "Logger.logMessageAsync.#createUUID()#"
action = "run"
newmessage = newMessage
{
logMessageSync( newMessage );
}
}
// I execute the logging SYNCHRONOUSLY.
private void function logMessageSync( required string newMessage ) {
lock
name = filepath
type = "exclusive"
timeout = 5
{
var logFile = fileOpen( filepath, "append", "utf-8" );
fileWrite( logFile, ( newMessage & chr( 10 ) ) );
fileClose( logFile );
} // END: Lock.
}
}
</cfscript>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment