Paolo Broccardo
Paolo Broccardo

Reputation: 1744

ColdFusion performance and locking optimisation

I have a link that will allow users to click it and it fetches a zip file of photos. If the zip file doesn't exist, it then starts a thread to create the zip and displays a message back to the user that the photos are currently being processed.

What I'm trying to avoid is a user clicking the link repeatedly and setting off a whole mass of threads that will try create/update the zip file. The zip file processing is quite system resource intensive so I only want to allow the application to generate one zip at a time. If one is busy being compiled, it should just do nothing and queue the requests.

Currently how I am handling it is with a cflock around the thread:

<cflock name="createAlbumZip" type="exclusive" timeout="30" throwontimeout="no">
  <cfthread action="run" albumId="#arguments.albumId#" name="#CreateUUID()#">
    ....

What I am hoping occurs here (it seems to be working if I test it) is that it will check if there is currently a thread running using a lock called 'createAlbumZip'. If there is, it will queue the request for 30 seconds after which it should timeout without any error. If it wasn't able to create it within the 30 seconds that is fine.

So - this seems to be working, but my question is: Is this the best way to handle a scenario like this? Is locking the right approach? Are there any shortcomings that could arise from this approach that I don't see?

Upvotes: 2

Views: 264

Answers (2)

Adam Tuttle
Adam Tuttle

Reputation: 19804

There are a million ways to skin this cat. Locking is a good start, and as per your comment on @Pat Branley's answer, I think your locking outside the thread creation might be a little more efficient for just the reason you propose: the potential would exist to create dozens of threads whose whole lifespan will consist of waiting for a lock to open or timeout.

The other thing you need to do is double up on the IF statement:

<cfif not (zip file exists)>
  <cflock ...>
    <cfif not (zip file exists)>
      <cfthread>
        ...create zip...
      </cfthread>
    </cfif>
  </cflock>
</cfif>

This will prevent the case where thread B is waiting while thread A creates the zip, and then thread A finishes, and thread B proceeds to recreate/overwrite it.

In addition, you could consider something like using JavaScript to prevent extra clicks by disabling the button/link after it's been clicked.

Upvotes: 2

Pat Branley
Pat Branley

Reputation: 9

I think you have that code around the wrong way. What you are saying is 'only one thread is allowed to spawn this new thread'. Now that may work in your case because you have the timeouts set such that nobody can create another thread so there is no chance two threads are executing at once.

what you want to say is 'only one thread is allowed to make a zip'. So I would do this

<cfthread .... >
  <cflock>
   ...zip....

Upvotes: 0

Related Questions