Ask a Jedi: Using Sleep ok?

This post is more than 2 years old.

Danny asks a question about locking and sleep in his ColdFusion/Flex application:

I'm wondering if it is good practice to use java.lang.Thread.sleep(). I have a Flex App uploads image files (in a loop) to a CF Server. In brief, I am Reading, Uploading, Deleting images all within short times of each other, so there is a chance my Delete will fail because my Flex App may still be reading the image, thus locking it.

I decided to just call a Sleep(20000) before I called Delete. With 3 files, my Flex App was seemless. But when I tried 6 files, my Flex App stalled a bit.

Maybe it is because I am just using the Developer version of ColdFusion, but is calling all these Sleep threads causing ColdFusion to block my Flex App or something? Is this the right way to go about this?

I'll start by reminding folks that in ColdFusion 8, you have no need to go to Java, you can just use Sleep() natively as part of the application.

So I think you can see the nature of your problem. You are trying to solve your locking problem by waiting - and while it works for short sets of files, it isn't working for more. You can certainly just double the number in your Sleep call, and that may work, but you will never be certain.

You want to watch out for code like this. I think we've all done it. Call it "Hail Mary" code. Code you think might work - but you aren't sure. You shouldn't write it - but I know I have in the past.

I'd recommend another solution. If I read right, it sounds like the only problem you have is deleting. Why not simply use a scheduled task? It can run hourly and use cfdirectory to find images that are more than 60 minutes old and delete them. In theory, they could still be locked so you want to be sure to try/catch the delete call.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Ben Nadel posted on 10/15/2007 at 6:49 PM

I don't know how FLEX applications talk to images. If the FLEX app is reading the image file directly, then that's another story. However, if the image file is being served up via ColdFusion (ex. CFContent), then you could put file-name-based locks on the file read / delete code. This way, ColdFusion would essentially sleep while waiting for the "read" code to finish.

Of course, this puts a lot of additional work on the CF server for the CFContent tag. I wouldn't suggest moving to CFContent if you are NOT already using it, but if you are, CFLock would do what you need (just put in a relatively high timeout).

Comment 2 by Raymond Camden posted on 10/15/2007 at 6:52 PM

But I would argue against even bothering. Why make CF wait? Just clean up the files later on. Now obviously if you have billions of files you may want to clean up sooner rather than later.

Comment 3 by Dave Ferguson posted on 10/15/2007 at 6:53 PM

Typically I avoid doing any sleep type actions when they could affect user experience. I would also suggest doing this in a scheduled task. However, if that does not work there is an alternative. You could run the delete procedure as an Asynchronous process. This would allow for the delete to be much more immediate than a scheduled task as well as not impacting the user.

--Dave

Comment 4 by Ben Nadel posted on 10/15/2007 at 6:56 PM

@Ray,

I agree. The bulk delete once or twice a day is gonna be the easiest thing to do.

Comment 5 by Raymond Camden posted on 10/15/2007 at 7:00 PM

Dave - I'd worry about that too. Would you write the code to keep trying to delete? Ie a conditional loop? I guess that wouldn't be too bad - but I'd worry about it possibly looping for too long, taking up a precious thread.

Comment 6 by todd sharp posted on 10/15/2007 at 7:25 PM

What about using the directory watcher gateway??

Comment 7 by Joe Rinehart posted on 10/15/2007 at 7:29 PM

Why not have the Flex app call a heyImDoneWithFileId(fileId) method back on the server when it's done reading the uploaded image, and have that do the delete?

On top of that, a scheduled task to clean up the trash in case the call never happened would still be needed...

Comment 8 by Nolan Erck posted on 10/15/2007 at 8:01 PM

On a semi-related note, I recently uploaded fakesleep() to cflib.org (currently in the queue). Some hosting providers have CreateObject("java") turned off, which keeps the Java sleep() from working (I haven't tried CF 8's native sleep() yet, but if it does the same thing internally, that one may not work either).

My version noted above just uses getTickCount() in a loop to pause the current page. It might be a better solution for some folks (assuming they have hosting providers that are as strict as my last one was).

hth
nolan

Comment 9 by todd sharp posted on 10/15/2007 at 8:38 PM

Blocking access to CF Java functions wouldn't break CF 8's sleep() - if that were the case half the language would be broken by blocking that access. That feature only blocks direct invocation of those objects by your code - not the CF internal stuff.

Comment 10 by Danny Nip posted on 10/15/2007 at 8:41 PM

Thanks for bringing up this discussion Ray.

A bit more detail if anyone was curious. I was essentially loading up thumbnails that were stored on the hard drive into Flex using an <mx:Image> tag (non-Embedded). So in this page, the user could view and update an image. Hence, the read/update/delete in rapid succession.

So does calling Sleep() eat up a precious thread in ColdFusion?

Comment 11 by Raymond Camden posted on 10/15/2007 at 8:49 PM

If it stops the page from ending, I'd consider it bad, especially with the option to just clean up later.

Comment 12 by Raymond Camden posted on 10/15/2007 at 9:30 PM

Todd - I think the Dir Watcher EG would not be a good idea. It could fire off while the file is still locked.

Comment 13 by Nolan Erck posted on 10/15/2007 at 10:48 PM

@Todd

Actually, that's not entirely true (at least not for CF7). I had issues where cfdump wouldn't work on hosts that turn off CreateObject(java) as well -- which uses it internally. Same problem, even for built-in CF tags.

It was, to say the least, profoundly annoying to deal with. :)

Comment 14 by Raymond Camden posted on 10/15/2007 at 11:05 PM

CFDUMP is actually built in CFML. It is a custom tag. That may make it different than sleep().

Comment 15 by todd sharp posted on 10/15/2007 at 11:44 PM

cfcache, cfcomponent, cfsavecontent, cftrace are also custom tags i believe

Comment 16 by Raymond Camden posted on 10/15/2007 at 11:45 PM

Actually - I think cfcomponent is a CFC.

Comment 17 by todd sharp posted on 10/15/2007 at 11:46 PM

Nod - as well as interface.

Comment 18 by Rob Rawlins posted on 10/17/2007 at 7:51 PM

Its times like this when we need a 'finally' block in our try/catch handlers :-D I've suffered at the hands of problems like this when working with Python and I always found that commensing the delete in the finally block always kept things rather safe as the application wouldnt proceed to that block untill the try had completed successfully, I've always found sleeps a HIGHLY inefficient way of handling this kind of stuff.

Have they added a feature like this into cf8? would be a nice touch.

I'm inclined to go with these guys for a bulk delete, although you might want to consider doing it with somthing other than CF, if you have large numbers of files then it'll run as a very slow task. Thats how I currently handle things on my application and I see a very large amount of files being built on my server.

Rob

Comment 19 by Raymond Camden posted on 10/17/2007 at 7:58 PM

CF8 did not add FInally.

Comment 20 by Rob Rawlins posted on 10/17/2007 at 9:00 PM

Thanks for clearing that up Ray, perhaps its a wishlist addition for numero 9.

Rob