Last active
February 25, 2023 23:14
-
-
Save j05u3/c4a21e73f212ae1f6e411486ccace8fd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { fdb } from "../firestore-init"; | |
export interface ExternalResourceLockDocument { | |
isLocked: boolean; | |
} | |
export class ExternalResourceLock { | |
constructor(public readonly collection: string, public readonly docId: string) { | |
} | |
async acquireLock() { | |
const ALREADY_LOCKED = "ALREADY_LOCKED"; | |
const docRef = fdb.collection(this.collection).doc(this.docId); | |
try { | |
return await fdb.runTransaction(async t => { | |
const doc = await t.get(docRef); | |
const data = (doc.data() as ExternalResourceLockDocument | undefined) ?? { | |
isLocked: false, | |
}; | |
if (data.isLocked ?? false) { // we have a fallback here because the document might not | |
// have had a lock before | |
throw ALREADY_LOCKED; | |
} else { | |
data.isLocked = true; | |
t.set(docRef, data); | |
} | |
return data; | |
}, { maxAttempts: 10 }); | |
} catch (e) { | |
if (e === ALREADY_LOCKED) { | |
console.log(`ExternalResourceLock: already locked: ${this.collection}/${this.docId}`); | |
} else { | |
console.error(e); | |
throw e; | |
} | |
} | |
return null; | |
} | |
async releaseLock() { | |
const docRef = fdb.collection(this.collection).doc(this.docId); | |
const newDoc : ExternalResourceLockDocument = { isLocked: false }; | |
await docRef.set(newDoc); | |
} | |
async isLocked() { | |
const doc = await fdb.collection(this.collection).doc(this.docId).get(); | |
return (doc.data() as ExternalResourceLockDocument | undefined)?.isLocked ?? false; | |
} | |
/** | |
* Just for testing purposes, you should not need to use this. | |
* Deletes the document. | |
*/ | |
async deleteDoc() { | |
await fdb.collection(this.collection).doc(this.docId).delete(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment