Alexander Soare
Alexander Soare

Reputation: 3267

Can I use a LockService across two functions?

The LockService documentation states that I can lock access to one section of code, but with if there are two functions which access the same sheet in my SpreadSheet?

Is there a way to stop both functions trying to access that sheet concurrently?

Right now my work around is to set and unset a script property via the Properties Service:

{
  'lock': True
}

The problem here of course, is that if one of my functions fails midway the lock state will be permanently in place.

EDIT

Upon the request of commenters here is some pseudocode for the two functions in question

SHEET = SpreadsheetApp.getActive.getSheetByName('Sheet 1')

// clock trigger to run this once every 5 minutes
function funcA() {
  range = SHEET.getRange('C2:E')
  vals = range.getValues();
  updatedVals = doSomeProcessing(vals);
  range.setValues(vals);
}

// clock trigger to run this once every 6 hours
function funcB() {
  range = SHEET.getRange('A2:Z')
  vals = range.getValues();
  updateVals = doSomeOtherProcessing(vals);
  range.setValues(vals);
  sheet.sort(1);
}

So the problem is if funcA reads from SHEET, then funcB sorts, then funcA writes back to SHEET. (and there are probably other possible issues).

Upvotes: 0

Views: 93

Answers (1)

Alessandro
Alessandro

Reputation: 2998

Approach

During concurrent access to a shared resource you can use Apps Script LockService to prevent race conditions.

Here a simple example on with your two functions funcA and funcB:

// this function takes 10 seconds to run, waits 5 seconds for the lock to be released otherwise it fails.
function funcA() {
  var lock = LockService.getScriptLock(); // gets the lock from the LockService 
  try {
    lock.waitLock(5000); // Tries for at most 5 seconds to get the lock
    Utilities.sleep(10000);
  } catch (e) {
    Logger.log('funcA could not obtain lock after 5 seconds.');
  }
}

// this functions takes 20 seconds to run, waits 5 seconds for the lock to be released otherwise it fails.
function funcB() {
  var lock = LockService.getScriptLock();
  try {
    lock.waitLock(5000);
    Utilities.sleep(20000);
  } catch (e) {
    Logger.log('funcB could not obtain lock after 5 seconds.');
  }
}

You can try easily the lock behavior calling function A right after function B.

Reference:

LockService

Upvotes: 1

Related Questions