We all want our custom apps to be faster, right? As problem solvers, we design our system and complex processes to happen quickly so that the user can get on with her task. Well one method we have at our fingertips is FileMaker Perform Script on Server. Let’s discuss this script step, its features and things to watch out for. As we study it and use it properly, we’ll use this script step like a boss.
Filemaker Perform Script on Server
This small-seeming script step was introduced in FileMaker 13. Its purpose is to, as it is called, perform a script on the server. Of course this only applies if a file is actually hosted. You can specify a script in the current file or external data source file, run it up on the server, and get back the result. We’ll look at why this was such a game changer below.
Perform Script on Server (P.S.O.S., as FileMaker devs like to call it) works in FileMaker Pro, FileMaker Go, and WebDirect. It is not supported in Runtimes, and it doesn’t make sense in Server schedules–scheduled scripts already perform on the server.
Along with the script name and the parameter, you can specify to “Wait for Completion”. We’ll get into this more later.
Complex tasks take up a lot of computing power and time when run against hosted data on a client machine. As of FileMaker 15, records are cached in the local machine, but FileMaker still might have to fetch new records, process them in some way, and then send the updated records back to the server. That’s a lot. FileMaker Perform Script on Server does the complex tasks right there on the server, where the records are actually sitting. There’s no transfer of data back and forth. Server simply does the work, then updates the client cache with any changed data. The difference in time between the same script running on the client and the server is noticeable.
With great power . . .
As with most things in life, when you’re given a great tool, precautions must be taken and your eyes need to be extra vigilant. Perform Script on Server, too must be handled carefully.
Who is performing the script?
When the PSOS script step is called, it opens the file on the server with the same security as the current user invoking this script step. If I log into the hosted file on my machine as “jbrown” with a privilege set of “HR”, any PSOS script I run will operate with those same security settings. The log in for PSOS is very similar as mine in terms of security, but nowhere is a UI drawn as I would see it on my machine. FileMaker Server can open the file and perform the script with no interface. This login also opens up and runs the onFirstWindowOpen script. If the first-run script sets globals and go to a “dashboard” layout, then PSOS will do the same. Even though it logs in with my username and password, it still is the server running the script. So any functions that return the current time/date, will return Server’s current time and date.
Context is king
FileMaker Server is powerful, but when a PSOS script is called and FMS begins the work, it has no idea where to begin. At the end of the PSOS’s login process, the script is on the onOpen layout, but that’s often not the context in which you want to perform some processing data. So you need to explicitly add a script step in the PSOS script to go to a specific layout. Additionally, it is vital to make sure all globals used in the rest of the script are updated as necessary.
Likewise, any values set in fields with global storage or global variables will be empty. Even if a global field or variable was set in the client file, they do not exist in the PSOS session.
Just like the context and global values, the FileMaker Perform Script on Server script doesn’t know which records upon which to work. The script running on the client, the one that called PSOS in the first place may have found some records, but that means nothing to the work done on the server. So in some way, PSOS needs to know which records to find. And you can do this in many ways. Here are just a few:
- Do the find of records in the PSOS script itself. Let FileMaker Server find the records. But of course, you’ll have to tell the PSOS script which records to find. And that can be done by passing the find criteria in as a parameter of the PSOS script.
- Do the find in the script performed on the client. Pass the primary keys of the entire found set up to the FileMaker Perform Script on Server script. Include in this script a layout on which is a field. In this field is placed the primary key list. FInally use Go To Related Records to go to the correct context from the starting point of this field.
What edits to make
Once PSOS has the found set, it is vital to tell it what to do with these records, what updates to make. Again, since the client script probably has that info, the PSOS script step must pass this information up to the server. Along with the find criteria, I’d pass this up to PSOS as a JSON object. We often use fields with global storage as places people can enter find criteria. Those aren’t available in the PSOS, so we have to pass it up. Here’s a sample of what I did while working with my user group colleague.
The first item was the find criteria. The remaining items were used to update the found set of records. Both the find criteria and the update info were generated in the client-run script based on user choices.
Just as a client-run script, if a record is locked, the FileMaker Perform Script on Server script cannot update that record. If we’re in the middle of a loop and the 47th record is locked, it won’t get updated. We have to handle that in some way.
We advocate a transactional approach to handle records that might be locked. If all of them should be processed or none of them, transactions are the way to go.
PSOS cannot be debugged in the normal sense using the Data Viewer and Script Debugger, so instead we have to find all the errors in our code and eliminate those. But we also have to prepare for unexpected events. To the former, as we work on the script, we can choose to run it on the client instead and debug it using the normal tools. We work through the script and make sure that everything works as expected. We also make sure that the script goes to the right context and finds the right records.
Unexpected events happen, and unexpected events could happen in the PSOS script, and that could cause major issues. So we have to be extra diligent in bailing out of the script whenever an error is encountered that would break the rest of the script processing. Here are a few times you’d want to bail out of the PSOS script when an error occurs
Possible Errors to check
- There are no records in the found set.
- The PSOS session fails to go to the correct layout
- A record fails to update (though you may want to handle this differently. Rather than bailing out of the PSOS script, simply log the record that is uneditable).
The bail out process is pretty simple: After setting Error Capture to be On, get the error of the previous step. If it is not 0, then exit the script with that error code as the exit parameter:
Set Error Capture [On] … Perform Find Set Variable [$json ; JSONSetElement ("" ; "error" ; Get(LastError) ; JSONNumber )] If $error <> 0 Exit script [ $json] In the client script, the one that called the PSOS script, use Get(ScriptResult) and see what error took place: JSONGetElement ( $result ; "error").
Wait for it
Finally, the option to Wait for Completion in the FileMaker Perform Script on Server, which is on by default, simply tells the calling script to wait for the PSOS script to finish its work. In most cases, you want this. The script on the server is working, processing a bunch of records. That process needs to finish before the client script can continue. But it is possible to uncheck this option and allow the script to work on its own. There seem to be a smaller number of times when you’d want this, but it is possible.
Perform Script on Server: Use it
FileMaker Perform Script on Server is a powerful tool that offloads complex processes to the server. When used properly and when considered carefully, its use can speed up the processing of data for your users.