September 8, 2015 Blog FileMaker Techniques FilemakerFileMaker 14FileMaker TechniquesPerform Script on ServerPSoS Perform Script on Server Automatically The ability of FileMaker Pro to perform a script on the server instead of locally on the client’s machine is a huge potential boon for productivity. Tasks for which a user might otherwise have to wait to complete can be accomplished in the background without causing a delay. Performing certain scripted tasks on the server is also much, much faster in many cases. So, it’s nice to perform a script on the server whenever you can. Conditions Needed for PSoS Of course, you can’t use “Perform Script on Server” (PSoS) if you don’t have the following three conditions present: You have to be running a hosted FileMaker database The server that hosts it must support PSoS (v13 or v14) The script has to be compatible with PSoS (and set up to run that way) While working on our second FileMaker module, fmRecentRecords, we perfected a neat scripting trick for automatically running a script on a server, whenever possible. The specific code is shown below, but it basically works this way: First, the script needs to determine if the file is actually hosted (using Get (ConnectionState) ). Next, it needs to determine what version of FileMaker Server is hosting the file (using Get (HostApplicationVersion) ), and if that version is one that can handle PSoS (using PatternCount to look for the version numbers we require: 13 or 14). Once it’s determined that the file is hosted by a version of FileMaker Server that can use PSoS, the script needs to know whether it is itself currently running on the local machine. If it is, then the script will recursevely call itself again using PSoS. Now the next time it runs (on the server), it will skip to the actual steps of the script we want to perform. If the file is not hosted, or is not hosted by a version 13 or higher server, then it will also skip the steps to call itself via PSoS, and the script just runs the rest of the procedure locally. The beauty of this is that you can use PSoS when it’s available, but still run just fine when it’s not. Check out the code below: Just insert some code like this into your script and you’re off and running… on server! By David Weiner
2 Comments Marc Berning Posted on 4:05 AM - July 26, 2016 If I may make a couple suggestions: 1. Get ( ConnectionState ) would return a 1 if the file were being hosted by a client via peer-to-peer, thus not entirely useful, and not really necessary. PatternCount ( Get ( HostApplicationVersion ); “Server” ) will get all the information that you’re looking for. 2. As written, your use of Get ( HostApplicationVersion ) will fail with version 15, and any future versions. Perhaps it would be more future-proof to write: GetAsNumber ( Get ( HostApplicationVersion )) >= 13. I use this basic technique often enough that I encapsulate the various tests into a custom function: PatternCount ( Get ( HostApplicationVersion ); “Server” ) and GetAsNumber ( Get ( HostApplicationVersion )) >= 13 and PatternCount ( Get ( ApplicationVersion ); “Server” ) = 0 Lastly, this technique can still fail if the server is too busy, so I always trap for an error immediately after the attempt. Thus I am left with: Loop If [ CF_PSOS_Available ] Perform Script on Server [ “Script to run using PSOS” ; Parameter: Get ( ScriptParameter ) ] Exit Loop If [ Get ( LastError ) = 812 // Exceeded Host Capacity Exit Script [ Text Result: Get ( ScriptResult ) ] End If Exit Loop if [ True ] End Loop David Weiner Posted on 5:14 PM - July 26, 2016 Marc, it’s funny, but I just in the last few days rewrote this as a custom function myself. I was sort of getting annoyed at the verbosity of all those the steps at the head of a script. My custom function looks like this: Let ( [ isHosted = Get ( ConnectionState ) ; isServer = PatternCount ( Get ( ApplicationVersion ) ; “server” ) ; serverVersion = Int ( GetAsNumber ( Get ( HostApplicationVersion ) ) ) ; isValidVersion = Case ( serverVersion ≥ 13 ; 1 ) ] ; Case ( isHosted and isValidVersion and not isServer ; 1 ) ) But now I realize, as you suggested, that I could remove the “isHosted” parameter entirely. This custom function will result in a boolean True if the script is running locally and can be performed on server. It will result in a False if the script is already running on server, and will then continue with the rest of the script. I didn’t think about the possibility of an 812 error, so that’s a great suggestion!