Concurrency and Google Apps Script

Monday, October 31, 2011 | 1:28 PM


Here’s the scenario: you create a form, you have a script that triggers onFormSubmit and all is well... until it gets popular. Occasionally you start having interlacing modifications from separate invocations of your script to the spreadsheet. Clearly, this kind of interlacing is not what you intended for the script to do. Up until now, there was no good solution to this problem -- except to remain unpopular or just be lucky. Neither are great solutions.

Now, my friend, you are in luck! We’ve just launched the LockService to deal with exactly this problem. The LockService allows you to have only one invocation of the script or portions thereof run at a time. Others that would’ve run at the same time can now be made to wait nicely in line for their turn. Just like the line at the checkout counter.

The LockService can provide two different kinds of locks-- one that locks for any invocation of your script, called a public lock, and another that locks only invocations by the same user on your script, called a private lock. If you’re not sure, using a public lock is the safest bet.

For example, in the scenario in the previous paragraph you would want something like this:

function onFormSubmit() {
  // we want a public lock, one that locks for all invocations
  var lock = LockService.getPublicLock();
  lock.waitLock(30000);  // wait 30 seconds before conceding defeat.
  // got the lock, you may now proceed
  ...whatever it used to do here....

It’s best to release the lock at the end, but if you don’t, any locks you hold will be released at the end of script execution. How long should you wait? It depends on two things mainly: how long the thing you’re going to do while holding the lock takes, and how many concurrent executions you expect. Multiply those two and you’ll get your timeout. A number like 30 seconds should handle a good number of cases. Another way to pick the number is frankly to take an educated guess and if you guess too short, the script will occasionally fail.

If you want to avoid total failure if you can’t get the lock, you also have the option trying to get the lock and doing something else in the event of not being able to get it:

function someFunction() {
  var lock = LockService.getPublicLock();
  if (lock.tryLock(30000))  {
    // I got the lock!  Wo000t!!!11 Do whatever I was going to do!
  } else {
    // I couldn’t get the lock, now for plan B :(
    GmailApp.sendEmail(“”, “epic fail”,
        “lock acquisition fail!”);

So now your scripts can be as popular as they can get with no worries about messing up shared resources due to concurrent edits! Check out the LockService documentation for more information.

Drew Csillag

Drew is a Software Engineer and Manager at Google on the Google Apps Script project, based in New York. He previously worked on Billing at Google, and for the 13 years before, he has worked on everything from hardware up to GUI frontends and everything in between.


DGG said...

How can i Add the tiff file in Google Earth (From .kml file)

Matt Z said...

So this stops the script from running the same section of the script more than once at a time.
How about the limit of concurrent times the script can be run?
I've used a script to build a UiApp in a Site but I now can't edit the script or run it from the UiApp, all I get is "There are currently too many people viewing this document. Please try again later."
Any advice? Luckily, I had a copy of the script, so I created an additonal instance of the script and that seems to be working again, but I'm just waiting for it to break.

Thomas P. said...

I have quite a few comment on the Lock Services Reference Documentation.
Please see

Ron webshed said...

Hello Matt, we have it also

I posted a bug issue:

please star it

Arcady_WebShed said...

I get the same message like Matt Z. said.
“There are currently too many people viewing this document. Please try again later.”
I have published web service
I get this message when I try to edit the script, and also when I try to invoke the service from an other script or browser url

It works great until November 1, 2011