Folder Action Recursion

Gday all,

I’m building a workflow where many files are processed and moved through a series of folders. While things work well manually dropping files on folders, the whole show comes to a screaming halt when certain conditions occur.

Specifically, if an action is already running and a bunch more files come into the folder the action seems to pause for no reason. I can get it to continue where it left off by opening the folder in the Finder. It’s as if the folder action script has been told to wait until something else happens to the folder. Sometime it works, sometimes not.

It seems to occur when the action is currently performing a lengthy finder copy. It happens whether I use Automator actions or applescripts as folder actions.

I’m guessing I’m not the first to have stressed out this technology. Could I ask anyone with experience in this for their opinion on whether folder actions can be relied upon to process all items as expected?

If there are known gotchas to avoid then I’m all ears. Perhaps there’s a limit to the number of times an action can be called before it’s completed, or maybe one shouldn’t call shellscripts from inside sub handlers.

FWIW, I’m on 10.4.8 using Intel kit.

Thanks very much for any help or advice. As you can see, I’ve been trying to trace where the problem might occur, but I’m beginning to think there’s a system limit I’m coming up against.

George

PS - and thanks for this forum, it’s a great resource.


property theDestination : "/PRODUCTION/RECORDED/"
property theDestinationFile : (theDestination as POSIX file)


on adding folder items to this_folder after receiving theseFiles
	do shell script "logger START " & theseFiles
	
	try
		
		repeat with theFile in theseFiles
			do shell script "logger INPUT " & theFile
			
			set theResult to finishedBusy(theFile)
			do shell script "logger BUSY " & theResult & "===" & theFile
			
			set theResult to moveFile(theFile)
			do shell script "logger MOVING " & theResult & "===" & theFile
		end repeat
		
	on error theParams
		do shell script "logger ERROR MAIN " & theParams
	end try
	
	do shell script "logger STOP "
end adding folder items to


--
-- finishedCopying - wait until file stops being busy
-- 
on finishedBusy(theFile)
	set sizeOne to 0
	set sizeTwo to 1
	
	repeat until sizeOne = sizeTwo
		tell application "Finder"
			set sizeOne to (size of (info for (theFile)))
			do shell script "logger WAITING " & theFile
			delay 3
			set sizeTwo to (size of (info for (theFile)))
		end tell
	end repeat
	
	return "BUSY COMPLETE"
end finishedBusy


on moveFile(theFile)
	do shell script "logger MOVING TO " & theDestinationFile
	
	try
		tell application "Finder"
			set theName to name of theFile
			set theResult to move theFile to theDestinationFile replacing yes
		end tell
	on error theParams
		do shell script "logger ERROR MOVING " & theParams
	end try
	
	
	return "MOVING COMPLETE"
end moveFile



on idle
	do shell script "logger IDLE... "
end idle



Model: MBP 17", Intel Core Duo, Xeon Xserve
Browser: Firefox 2.0.0.1
Operating System: Mac OS X (10.4)

A known problem with Folder Action scripts - while the Finder (and System Events) are engaged, Folder Action triggering can be unreliable. I’ve usually solved the problem (when I’ve had it) by switching from a Folder Action script to a stay-open on-idle script.

Further, as far as I know, an “on idle” handler is only useful in a stay-open script. Since yours has no exit (i.e. return 20) meaning do it again in 20 seconds, I think you’d best remove that and find some other way to detect that the job is done like checking whether the folder is empty.

Ah, thanks Adam. That’s the confirmation I needed. It’s a shame that doesn’t work reliably.

Does anyone know if a bugreport has been filed on this? Has this fault been known for a while?

George

Eons. It’s always been a problem with no easy way around it because AppleScript is single-threaded - it can’t spawn a thread to keep watch, and System Events (which notes the event, apparently) can’t inform the Script while it’s waiting for the Finder to reply from it’s AppleEvent to do the move. You could do the moving with a shell script whose output was directed to /dev/null, I suppose (which doesn’t tie up either the script or the Finder), but I find it easier to just run an stay-open idle handler. They don’t occupy much memory and they don’t tie up the CPU during the wait.