The LockService gives the capability to do this

This service allows scripts to prevents concurrent access to sections of code. This can be useful when you have multiple users or processes modifying a shared resource and want to prevent collisions.

Very nice, but it’s description is a little vague. At best we can prevent some piece of code (it’s not clear what the scope is exactly), being executed more than once at a time. This is good, but what I found I needed was to be able to put a lock on a specific resource, perhaps that is accessed from multiple places.

Named lock.

The characteristics of a named lock are the same as the LockService

  • Expires after some period of time
  • Can be unlocked on successful completion before expiry

With the important addition

  • can be one of multiple independent locks
  • can apply to an abstract resourced, identified by some name, not to a specific piece of code.

Approach

Note that this technique relies on the predictability of CacheService. Google warn that it’s not necessarily predictable, so at this point I’m not sure how robust this approach is, but I have many people out there using this now and haven’t had any issues reported.

I’m using the library from Database caching, to create a named key in public cache that serves as a key to an in use marker, and of course the LockService itself to prevent collisions while grabbing a piece of cache. Would be great to get your experiences using this library, which can take a copy of at

https://script.google.com/a/mcpher.com/d/Mpv7vUR0126U53sfSMXsAPai_d-phDA33/edit?usp=sharing

or by including library Mpv7vUR0126U53sfSMXsAPai_d-phDA33

or on github

Example

create a named lock


set a key

check to see if there is a lock on that key

get a lock

remove a lock

get info about a lock

Some more fancy things

adjust the expiry time for a lock (in milliseconds)

adjust the time to wait before giving up (in milliseconds)

use a variety of arguments from which to generate a named key

set a lock owner (will be a property of lock.getInfo() and is not part of the key)

Info contents

Even more fancy

Run the whole section of code in a protected lock anonymous function

Some tests

Lock instances

There is the concept of a lock ‘instance’. The purpose of this is so that, in the same instance of a script, you can choose whether or not a lock is inherited or independent within the script.

This means that you will always get a lock for a particular instance if you already have a lock, but a different instance with the same resource key will show as already being locked. This leaves you free to not worry about calling a ‘lock within a lock’ .

SetSameInstanceLocked

The purpose of instance locking is to enable the nesting of locks for the same instance without then interfering with each other. This means that taking a lock and then testing it with the same instance will return false – since as far as this instance is concerned it’s not locked out.

It is possible to modify this behavior with

in which case a lock on the same instance will lock out other attempts using the same instance

When a lock is attempted with the same instance, it is allowed immediately, and the expiry time updated

Whereas this would have to wait

A test with multiple triggers

In this example I trigger 10 fairly simultaneous executions of the code below, and protect the properties service where I’m holding the results, sleeping for a bit to provoke a lock collision and check that the properties have not been updated by something else in the meantime. In the results, the delay between started, and got lock, indicates that a wait for a lock to be released was happening while the instance with the lock was sleeping as intended.

results

Code from library

For more like this see Google Apps Scripts Snippets
For help and more information join our forum,follow the blog or follow me on Twitter.