{"id":2870,"date":"2013-05-03T12:22:09","date_gmt":"2013-05-03T16:22:09","guid":{"rendered":"http:\/\/www.red-sweater.com\/blog\/?p=2870"},"modified":"2013-05-03T12:47:32","modified_gmt":"2013-05-03T16:47:32","slug":"fire-and-forget-scripting","status":"publish","type":"post","link":"https:\/\/redsweater.com\/blog\/2870\/fire-and-forget-scripting","title":{"rendered":"Fire &#038; Forget Scripting"},"content":{"rendered":"<p>It\u2019s hard to believe <a href=\"http:\/\/red-sweater.com\/fastscripts\/\">FastScripts<\/a> is just over <a href=\"http:\/\/macscripter.net\/viewtopic.php?id=3965\">ten years old<\/a>. When I first started developing the app, one of my primary goals was to improve upon the relatively slow launch and execution time of scripts when using Apple\u2019s own built-in script menu. At the time, my analysis suggested that the sluggishness was primarily due to the time spent loading the script from disk into memory, and in launching a separate helper app to carry out execution of the script.<\/p>\n<p>To avoid this slowness, FastScripts adopted a strategy in which scripts are loaded into memory once, and kept ready to fire again at a moment\u2019s notice. This, combined with support for global and application-specific keyboard shortcuts, opened a whole new world of opportunities for streamlining workflows with frequently reused scripts.<\/p>\n<p>The approach comes with some drawbacks, however. For example, FastScripts can only run one script at a time. So if a script takes a long time to finish, it can be very frustrating to be locked out of the ability to run other scripts. Another issue is that occasional issues with Apple\u2019s AppleScript support make it possible for a script to hang indefinitely or even crash. If this happens in the context of FastScripts running a script, then obviously it\u2019s FastScripts itself that ends up hanging or crashing.<\/p>\n<p>For a long time I have considered the possibility of changing FastScripts so that it runs scripts in a separate process. It already does this by necessity for shell scripts such as Ruby or Python, but I have clung to the belief that doing so for AppleScript would eliminate one of the app\u2019s major advantages.<\/p>\n<p>I use FastScripts myself to run a variety of <em>extremely terse<\/em> scripts. For example I have scripts that open favorite web sites, activate specific applications, or simply play and pause iTunes. It would be extremely frustrating if any of these scripts exhibited even a slight delay.<\/p>\n<p>I am no longer convinced that the decade-old strategy of avoiding on-the-fly loading and running of scripts is providing any significant performance advantages. Macs have gotten faster in so many respects: faster RAM, faster disks, and faster and more numerous CPUs. <\/p>\n<p>I have been experimenting myself with a version of FastScripts that runs every AppleScript in a separate process, and have experienced no noticeable delays. And now when I do occaionally run a script that takes several seconds, or even minutes to run, I can fire it off with FastScripts confident that it will be ready to immediately run another script.<\/p>\n<p>If you are a FastScripts user and this sounds intriguing, the good news is you can try it out today. Just make sure you\u2019re up to date with version 2.6.5 from the Mac App Store or direct from the <a href=\"http:\/\/red-sweater.com\/fastscripts\/\">FastScripts home page<\/a>. Because I\u2019m still tentative about the performance, by default FastScripts continues to run scripts with the old, in-process behavior. To enable the new separate-process functionality, just set this &#8220;secret&#8221; preference key in the Terminal:<\/p>\n<pre>\ndefaults write com.red-sweater.FastScripts RSScriptingPreferSeparateProcesses -bool YES\n<\/pre>\n<p>If you do try this out and you also find performance is unaffected, please let me know in comments below. On the other hand, if you see a significant slowdown, that would be useful to know as well. And in case it\u2019s not obvious, you can revert to FastScripts\u2019s old behavior by re-running the line above with &#8220;NO&#8221; in place of &#8220;YES&#8221;. I will consider defaulting to separate-process execution in a future update, assuming performance is good across the board.<\/p>\n<p>In adding this functionality to FastScripts, I also considered that performance might not be great for all users, but there would nonetheless be cases where running a separate process would be preferable. For example if you have one script that you know will always take a long time to complete, you might want FastScripts to only bother with a separate process for that script. You can instruct the app to run it in a separate process by implementing a custom AppleScript handler in the script itself:<\/p>\n<pre>\non redSweaterScriptingPrefersSeparateProcess()\n\treturn true\nend redSweaterScriptingPrefersSeparateProcess\n<\/pre>\n<p>Now when FastScripts runs the script, you won\u2019t have to wait around for it to finish. Just fire and forget!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It\u2019s hard to believe FastScripts is just over ten years old. When I first started developing the app, one of my primary goals was to improve upon the relatively slow launch and execution time of scripts when using Apple\u2019s own built-in script menu. At the time, my analysis suggested that the sluggishness was primarily due [&hellip;]<\/p>\n","protected":false},"author":10,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-2870","post","type-post","status-publish","format-standard","hentry","category-fastscripts"],"_links":{"self":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts\/2870","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/comments?post=2870"}],"version-history":[{"count":5,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts\/2870\/revisions"}],"predecessor-version":[{"id":2875,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts\/2870\/revisions\/2875"}],"wp:attachment":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/media?parent=2870"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/categories?post=2870"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/tags?post=2870"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}