Avoid duplication of long-running threads
I started to use ColdFusion threads recently. I knew that they exist, but I saw no use for them in my code before. Recently I started to process large datasets and noticed that I don’t want the page to wait for processing. I can simply display information to the client, but perform processing it in the background.
The issue I faced was that sometimes the user (or the scheduled task) was not aware that the thread is already running, and executed the second one. To prevent this from happening I came with the simple method of locking the thread.
It can be used in a different programming language too – the only prerequisite is to find a method to pass the variable between various request executions. In ColdFusion, I’m using the application scope, but it can also be stored in the database or even a file.
The code is rather short:
<cfset threadAppName = "testApp"> <cfset timeLimit = 600> <cfif isDefined("application.#threadAppName#")> <cfset timePassed = DateDiff("s", application[threadAppName], now())> <cfoutput> <p>Thread is running - started #timePassed# seconds ago</p> <cfif timePassed GT 600> <p>Thread is running over #timeLimit# seconds, something wrong, removing lock.</p> <cfset structDelete(application, threadAppName)> </cfif> </cfoutput> <cfelse> <cfthread name="#threadAppName#" threadAppName="#threadAppName#"> <cfset application[arguments.threadAppName] = now()> <!--- do something time-consumming ---> <cfset sleep(10000)> <cfset structDelete(application, arguments.threadAppName)> </cfthread> <cfoutput><p>Thread started</p></cfoutput> </cfif>
Let’s analyze it part by part. In the beginning, I’m declaring what is the name of the thread (and the name of the variable to hold the lock). I’m also setting a time limit on which I assume that something went wrong. In the example above it is set to 10 minutes, but you should adjust it to fit your needs and your thread running time.
The first thing the script is doing is checking if the lock exists. If the variable is defined, it calculated the time passed and informs the user about the progress. If time is greater than the limit, the lock is removed.
If there is no lock, the script is creating a new thread and the first thing the tread does is to set the lock. The time-consuming operation is taking place in the thread. Once the operation is finished, the lock is removed. The text that is placed below the thread (“Thread started”) is displayed to the user immediately. The thread task is running in the background.
Of course, the above lack error handling, but you should get the idea 🙂