Skip to content

Instantly share code, notes, and snippets.

@segor
Last active November 9, 2021 05:08
Show Gist options
  • Save segor/0d727c630fb93194b01aff397762f82f to your computer and use it in GitHub Desktop.
Save segor/0d727c630fb93194b01aff397762f82f to your computer and use it in GitHub Desktop.
Wraps LockService with retry logic and fixes the "Too many LockService operations" Error. https://issuetracker.google.com/issues/112384851
/**
* Wraps LockService with retry logic and fixes the "Too many LockService operations" Error. https://issuetracker.google.com/issues/112384851
*/
class Lock {
constructor(lock) {
this._lock = lock;
}
waitLock(timeoutInMillis) {
return Lock._retry(() => this._lock.waitLock(timeoutInMillis));
}
releaseLock() {
return Lock._retry(() => this._lock.releaseLock());
}
tryLock() {
return Lock._retry(() => this._lock.tryLock());
}
hasLock() {
return Lock._retry(() => this._lock.hasLock());
}
static getDocumentLock() {
return Lock._retry(() => new Lock(LockService.getDocumentLock()));
}
static getUserLock() {
return Lock._retry(() => new Lock(LockService.getUserLock()));
}
static getScriptLock() {
return Lock._retry(() => new Lock(LockService.getScriptLock()));
}
static get retryMaxTimeMs() { return 30000; }
static _retry(func) {
const start = new Date();
let delay = 0;
let exc;
do {
try {
const result = func();
return result;
} catch (e) {
exc = e;
if (e.message.includes('too many LockService operations'))
Logger.log("WARNING: LockService operation failed and will be executed again. %s", e.stack);
else
throw e;
}
delay += 100;
Utilities.sleep(delay);
} while ((new Date() - start) < this.retryMaxTimeMs);
throw exc;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment