Apple Event timeout problems... Large script.
Apple Event timeout problems... Large script.
- Subject: Apple Event timeout problems... Large script.
- From: "Fox, Christopher B" <email@hidden>
- Date: Mon, 11 Jun 2001 15:11:26 -0400
Hello group:
I'm having some difficulty with a large script I've been asked to
maintain. The developer who initially coded the script is leaving prior to
the script being put into production. The script does have a couple of
issues remaining to be worked out, and that job has fallen on my shoulders.
The biggest problem I have is with large files. During one part of
the script, if the file size is too great, an error dialog box shows up on
screen "Apple Event timed out." and the script fails to continue executing.
The script works very well on small files. The code that is causing the
timeout is at the very bottom of the script. The problem seems to show up
most frequently over Airport. A wired connection seems to work a little
better, but may still occasionally time out.
Thanks for any help you can provide.
Christopher Fox
Macintosh Support
---------------- BEGIN SCRIPT
global g_serverOutputglobal g_serverInboxproperty workingFileList :
{}property crashFlag : boolean-- it'd be nice to have a propery that said
"hey, i've checked for this file 10 times and-- it still isn't back. I think
I'll give up now."-- wouldn't that be a nice thing to have?-- we can
uncomment this when I figure out how to pass variables between scripts--
property watcher : watcher of (load script alias ((path to scripts folder as
string) ,-- & "Libraries:PDF Server lib"))--
###########################################################-- ## this is the
watcher part of things-- ##-- ## this part of the script needs to maintain
the list of working files-- ## and periodically check the pdf server output
directory/folder for the files-- ## and when it sees a file, copy it to the
clientInbox-- ## then delete the file on the server and take the file out of
the list of -- ## working files, get it?script watcher property watchFolder
: "" property clientInbox : "" property outputFileList : {}
property thePath : "distill:output:" on run
-- first we set up some default locations for the 'inbox' and 'outbox'
tell application "Finder" set clientInbox to folder
"Inbox" of folder "PDF Creator" of disk "Macintosh HD" set
watchFolder to folder "output" of disk "distill" end tell
(* working file list is a list of records which have two fields, 'filename'
which is the original filename and extension (i.e. filename.ps) and
'mapping' which is the name of the file on the unix system what we need to
do here is get a list of the 'mapping' fields from the working file list,
and check that with the list of filenames on the unix server *)
set mappingList to {} repeat with i from 1 to length of my
workingFileList set theMapping to mapping of item i of my
workingFileList copy theMapping to the end of mappingList
end repeat -- get a list of files in the output
folder and run the checkFiles() -- routine to compare the two lists,
and get the file from the unix server -- if it's done set
outputFileList to list folder watchFolder if outputFileList is
not {} then checkFiles(mappingList) end if
end run on checkFiles(mappingList) set
thisItemExtension to "" repeat with a from 1 to
length of mappingList set anItem to item a of mappingList
-- right here we should set a counter field in the record for the item that
increments each time -- and after the count has been
reached the file should be dropped from the list --
setCheckCounter(anItem) set
theCounter to countOccurances(outputFileList, anItem) if
theCounter > 0 then -- get the original file
name set originalFileName to
getOrigFileName(anItem) end if if
theCounter > 1 then repeat theCounter times
-- get the extension set theExt to
getTheExtension(anItem)
-- copy the file getTheFile(anItem,
theExt, originalFileName) end repeat
else if theCounter is 1 then -- get the extension
set theExt to getTheExtension(anItem)
-- copy the file getTheFile(anItem, theExt,
originalFileName) end if
-- if necessary, do list maintenance if theCounter is 0
then exit repeat else
set my workingFileList to updateWorkingFileList(anItem, my workingFileList)
end if end repeat end
checkFiles on countOccurances(theList, theItem) set
theCount to 0 repeat with i from 1 to length of theList
set theHolder to item i of theList set oldDelim to
AppleScript's text item delimiters set AppleScript's
text item delimiters to "." set thisItem to the first
text item of theHolder set AppleScript's text item
delimiters to oldDelim -- now we have the filname part in
thisItem and the extension -- so it's time to compare
anItem from the mapping list to thisItem -- from the
outputFileList if thisItem is theItem then
set theCount to theCount + 1 end if end repeat
if theCount < 1 then set theCount to 0
return theCount else return theCount end
if end countOccurances -- this routine returns the original
filename minus the extension on getOrigFileName(theItem)
repeat with i from 1 to (length of my workingFileList) set
origFileName to "" set holdMapping to mapping of item i
of my workingFileList set stupidHolder to holdMapping
if theItem is in stupidHolder then set fnHolder
to fileName of item i of my workingFileList set
oldDelim to AppleScript's text item delimiters set
AppleScript's text item delimiters to "." set
origFileName to the first text item of fnHolder set
AppleScript's text item delimiters to oldDelim exit
repeat end if end repeat return
origFileName end getOrigFileName on
updateWorkingFileList(theItem, theList) -- ## then we need to clear
the entry for this item repeat with i from 1 to (length of
theList) set holdMapping to mapping of item i of
theList if theItem is holdMapping then
set itemIndex to i exit repeat
end if end repeat set itemToRemove to
itemIndex -- obtain everything before the given item
if itemToRemove = 1 then set firstPart to {}
else set firstPart to items 1 thru (itemToRemove - 1) of
theList end if -- obtain everything after the given item
if itemToRemove = length of theList then set
secondPart to {} else set secondPart to
items (itemToRemove + 1) thru (length of theList) of theList end
if set theList to firstPart & secondPart -- ## end
clearing the item from workingFileList end updateWorkingFileList
on getTheFile(theItem, theExtension, originalFileName) set fileName
to thePath & theItem & "." & theExtension set fileRef to alias
fileName tell application "Finder" set
dummyHolder to move fileRef to clientInbox with replacing
set the name of dummyHolder to originalFileName & "." & theExtension
if theExtension is "log" then set the creator type
of dummyHolder to "ttxt" set the file type of
dummyHolder to "TEXT" end if delete
fileRef end tell end getTheFile on
getTheExtension(theItem) set outputFileList to list folder
watchFolder repeat with i from 1 to (count of outputFileList)
set theFile to item i of outputFileList set oldDelim to
AppleScript's text item delimiters set AppleScript's
text item delimiters to "." set thisItemFileName to the
first text item of theFile -- if the two file names
match then get the extension if theItem is
thisItemFileName then set thisItemExtension to the
last text item of theFile return
thisItemExtension end if end repeat end
getTheExtension end script-- ##-- ## end watcher--
###########################################################tell application
"Finder" set outputFolder to folder "output" of disk "distill" set
outputFileList to list folder outputFolderend tellon open theseItems --
initialize the input file list set inputFileList to {} -- fresh
start? if crashFlag is true then set my workingFileList to {}
set crashFlag to false end if -- go through each item one at a
time repeat with i from 1 to the count of theseItems set thisItem
to item i of theseItems set the itemInfo to info for thisItem
set thisItemFileName to name of itemInfo -- not sure I need
to do this this way, but the first time -- through I'm
copying the item to the input file list variable -- and after
that, I'm copying the item to the end of the list if (length
of inputFileList) < 1 then copy {thisItemFileName} to
inputFileList else copy thisItemFileName to the
end of inputFileList end if -- for debugging
log "input file list is: " & inputFileList -- here we check the
file to see if it's a folder or an alias -- then we check the
filename for '.ps' if (folder of the itemInfo is false) and
(alias of the itemInfo is false) and ,
(checkFileName(thisItem)) then -- file checks out so we
need to get a new random file name set randomFileName
to getRandomName() -- and then get a record made for
the item which has the original filename -- and the
mapping to the random file name, which is the filename on the
-- unix machine set rec to {fileName:thisItemFileName,
mapping:randomFileName} -- the we copy the file to the
server processItem(thisItem, rec) --
we only copy the record of filename and mapping to the working
-- file list if process item worked out copy rec to the end
of workingFileList end if end repeatend openon idle try
if my crashFlag is true then set my workingFileList to {}
end if if workingFileList is not {} then tell
watcher run end tell
else quit me end if on error errorMsg number
errorNum set my crashFlag to true display
dialog "uh oh, I got an error: " & errorNum & return & errorMsg
error number -128 end tryend idle-- ok so this is a terrible hack, and
must be fixed, but it works in a majority of caseson checkFileName(thisItem)
set the itemInfo to info for thisItem set thisFileName to name of itemInfo
if the thisFileName does not contain ".ps" then display dialog "File
name must be filename.ps." & return & "Please rename the file and try
again." return false else return true end ifend
checkFileNameon getRandomName() set maxNameLength to 5 set newName to ""
repeat maxNameLength times set x to random number from 1 to 3
if x = 1 then set y to random number from 48 to 57
else if x = 2 then set y to random number from 97 to
122 else if x = 3 then set y to random
number from 97 to 122 end if set x to ASCII character y
set newName to newName & x end repeat return newNameend
getRandomNameon processItem(thisItem, rec) -- these have to be
initialized in this scope, I think set g_serverInbox to "" set
g_serverOutput to "" set g_scriptName to "laser" -- try to
set the globals, if we can't try to mount the server try tell
application "Finder" -- the name of the inbox folder is
of course going to depend -- on the name of the script
set g_serverInbox to folder g_scriptName of disk "distill"
set g_serverOutput to folder "output" of disk "distill" end tell
on error errorMsg number errorNum log "Error is: " & errorNum
log "Error is: " & errorMsg if (errorNum = -1728) then
log "thisItem is: " & thisItem set useName to "xxxxx"
set usePass to "xxxxx" set useServer to "lock"
set useVolume to "distill" set errNum to 0
try mount volume "afp://" & useName & ":" &
usePass & "@" & useServer & "/" & useVolume --
we need to insert a little wait here delay 5
on error number errNum if errNum is not 0 then
display dialog "We failed to log on to the server." & ,
"Please use the Chooser to mount the server" & return & ,
"or contact Mac Support." buttons "OK" default button 1 with icon stop
error number -128 end if end
try -- end try else if (errorNum = -15267)
then display dialog , "You
are trying to copy a file onto the server that already exists. That's bad."
else display dialog "Please contact xxxxx ,
and tell him you got an error number: " & errorNum end if end
try -- the server should be mounted at this
point so try again to set the globals tell application "Finder"
if g_serverInbox is "" then set g_serverInbox to folder
g_scriptName of disk "distill" set g_serverOutput to folder
"output" of disk "distill" end if --
copy file, and I guess this might seem a little strange (and it probably is
-- but hey, this is applescript we're talking about) but I move and rename
in -- one step because the move command returns a reference to
the file -- you just moved, which is what we want
-- this is where the code times out on large file copies...
set nameHolder to the name of thisItem set the name of thisItem to
mapping of rec move thisItem to g_serverInbox with replacing
set the name of thisItem to nameHolder end tellend
processItem
**************************************************************************
The Information transmitted herewith is sensitive information intended only
for use to the individual or entity to which it is addressed. If the reader
of this message is not the intended recipient, you are hereby notified that
any review, retransmission, dissemination, distribution, copying or other
use of, or taking of any action in reliance upon, this information is
strictly prohibited. If you have received this communication in error,
please contact the sender and delete the material from your computer.