Script Actions and Independence

Reference:        Programming a Script

                        Script Editor

The first thing to understand about scripts is that all file and program execution actions are independent of one another.  When a script is processed, the various actions defined in the script are placed into queues for processing.  They are released from the queues based on time, and are limited only by the maximum server and transfer values defined for the script.  The order of the actions as they are written in the script may not correspond to the order in which they are processed.  Consider a simple example where you wish to transfer a file and then delete the original. You might program this as follows:

            :From: C:\Source\Test.file
            :To:      {ftp:Server}C:\Target\Test.file

            :Delete_Files:C:\Source\Test.file

Both actions are queued for immediate processing.  The transfer is started, and the delete is processed immediately after the transfer begins.  If the transfer process is quick enough, the delete may work and the script performs as you expect.  If the file is large and gets opened quickly, the delete may find it in use and fail.  If the transfer task does not get the file opened quickly, the delete may work and the transfer may fail since the source file is now missing.  In other words, the results are unpredictable.

Independence allows Beyond FTP to process multiple actions simultaneously, to retry failed actions while continuing to “keep the ball rolling” by processing later actions during the time the retried entries are waiting, and to efficiently manage transfers to more than one server.  The drawback is that it requires the script designer to be aware of those situations where a specific order must be maintained.  The general rule is this:

All script actions are asynchronous unless synchronous behavior is specifically enforced. 

Beyond FTP provides two ways to control precedence.  The first is to simply wait for preceding actions to be completed.  This is accomplished using the Wait_For_Completion command as follows:

            :From: C:\Source\Test.file
            :To:      {ftp:Server}C:\Target\Test.file

            :Wait_For_Completion:

            :Delete_Files:C:\Source\Test.file

The problem with this approach is that the source file will be deleted even when the transfer fails!  A better solution is to test the completion status of each command using the If/End_If command set.  These commands divide the script into separate blocks.  The rule is this:

All actions preceding an IF, Else, End_If, While, End_While, or Wait_For_Completion command must be completed before any action following the command will be processed

The test for successful completion verifies the status of all actions in the script since the last conditional command.  If these actions are successful, the CompletedOK test is true.  Otherwise the test is false.  This allows us to remove the preceding ambiguity as follows:

            :From: C:\Source\Test.file
            :To:      {ftp:Server}C:\Target\Test.file

            :If: Copies CompletedOK
                        :Delete_Files:C:\Source\Test.file

                        :If: Not Delete CompletedOK
                                    :Stop:
                        :End_If:
            :Else:
                        :Stop:
            :End_If:

Now, the transfer will run to completion and be tested for success.  If the transfer fails, the script will end.  If the transfer succeeds, the source file is then deleted.  We also test for a successful delete.