isBusy(), isDone() etc

RE:
http://bbs.applescript.net/viewtopic.php?t=9660
http://bbs.applescript.net/viewtopic.php?t=9654
http://bbs.applescript.net/viewtopic.php?t=9632
http://bbs.applescript.net/viewtopic.php?p=33672

The various isBusy() and isDone() solutions proposed in the above threads have only worked for me to an extend.
ftp-ing a file into the folder, things seem to work fine. But all kind of weird situations were observed when Windows FileSharing is used to copy the files to the Mac-folder (see the above threads for examples)

I have now worked out a different framework that allows a folder action to only begin its action when the file has been received.
In my testing, this turned out to be far more robust than the earlier proposals, on which the following draws.

Specifically, I found the decoupling of the two questions “Is file still growing?” and “Is file open for write access?” to be very important.
In my approach, outlined below, these questions are asked independently of each other, one after another. This seems to prevent many issues when Windows filesharing is involved.

To answer both questions, my approach relies completely on standard unix commands, which seem to give a much better control. The basic outline of my folder action is as such:


--folder action handler
on adding folder items to this_folder after receiving added_items
	--do for every added item
	repeat with this_item in added_items
		try
			--process added items one after another
			ProcessItem(this_folder, this_item)
		end try
	end repeat
end adding folder items to


--subroutine that processes items that were added to a folder
on ProcessItem(this_folder, this_item)
	
	--check if file is growing using UNIX "ls" command
	set LastFileSize to -1
	set isGrowing to true
	repeat until isGrowing is false
		set CurrentFileSize to do shell script ("/bin/ls -l " & (quoted form of (POSIX path of (this_item))) & " | /usr/bin/awk '{print $5}'")
		if CurrentFileSize is equal to LastFileSize then
			set isGrowing to false
		else
			set LastFileSize to CurrentFileSize
			delay 2
		end if
	end repeat
	
	--check if file is busy using UNIX "lsof" command
	set isbusy to 1
	repeat until isbusy is 0
		set isbusy to ((do shell script ("echo `lsof " & (quoted form of (POSIX path of (this_item))) & " | wc -l`")) as integer)
		if isbusy is not equal to 0 then
			delay 5
		end if
	end repeat

	--once the script arrives here, the file in question is not growing and is not busy anymore
	--this has been tested for all kinds of file sizes (up to 1,2GB) and protocols (FTP, SMB)
	--now that the file is ready, begin your processing
	--you should check here if the file exists, because the Windows copy process could have been aborted by the user
end ProcessItem

feel free to test this framework for yourself, and post back comments and suggestions

cheers
-captnswing

You’re right- good call!!! It seems that SMB transfers don’t like or ignore an attempt to ‘open access’ from the AS command. :shock:
The ‘lsof’ command is the ticket! I took the liberty of updating the isDone() handler and you have the credit accordingly in the code. Thanks for your input.