Search code examples
google-apps-scriptreentrancy

Is the Lock by the LockService in google app script reentrant or non-reentrant?


I am experimenting on implementing a simple row level locking for google sheets. (Conscious about concurrent accesses butching the data. Am I just being paranoid?). I've come across the LockService and was planning on using it but was just curious what kind of lock it is.


Solution

  • Answer:

    LockService is a mutual-exclusion lock, which, if used to guard script-external data, such as the PropertiesService methods which do not use user-specific properties, allow the code to be re-entrant.

    The Lock provided by LockService can be claimed multiple times without blocking itself.

    More Information:

    The LockService contains a Lock class which is a representation of a mutual-exclusion lock.

    From the documentation:

    Class Lock

    A representation of a mutual-exclusion lock.

    This class allows scripts to make sure that only one instance of the script is executing a given section of code at a time. This is particularly useful for callbacks and triggers, where a user action may cause changes to a shared resource and you want to ensure that aren't collisions.

    The example given on the documentation page appears to be outdated [1], however the example still shows how re-entrancy can be achieved if the following rules are adhered to:

    • Only local variables are used within a script
    • Any variables with global-scope (in the case of Apps Script, PropertiesService properties) must be locked inside a mutual-exclusion lock.
    • Any read/write methods of data external to what is contained within a script (Sheets data, modifiable Form responses, etc) must be locked inside a mutual-exclusion lock.

    In the case of editing Sheets, the SpreadsheetApp.flush() method is suitable enough for most operations, provided that they are used with high frequency density in a script which does not contain many edits - any algorithm with complexity larger than O(1) [2] for Sheets edits would need to be spaced with a flush() for high reliability, as long as there are not large value or structural edits to the sheet.

    If you have serious concurrent execution concerns, see yourself needing to add in surpluses of 2-3 SpreadsheetApp.flush() lines, or have an external read/write algorithm complexity large enough (O(N) or higher), then a Lock would be preferred.

    Notes:

    1. ScriptProperties has been deprecated in favour of PropertiesService methods
    2. Or O(N) for significantly small N, if and only if the lines of code don't read or write large data sets

    References:


    Related Questions: