Skip to content

Instantly share code, notes, and snippets.

@codyzu
Last active May 5, 2020 15:04
Show Gist options
  • Save codyzu/8c4cb531f640a700d67d6bcf8cb013b9 to your computer and use it in GitHub Desktop.
Save codyzu/8c4cb531f640a700d67d6bcf8cb013b9 to your computer and use it in GitHub Desktop.
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const {nanoid} = require('nanoid');
admin.initializeApp();
exports.withLock = functions.pubsub
.schedule("0 * * * *")
.onRun((context) => {
const { eventId, timestamp } = context;
const executionId = nanoid();
const lockRef = admin.firestore().collection("locks").doc(eventId);
const locked = await admin.firestore().runTransaction(async (transaction) => {
const lockSnapshot = await transaction.get(lockRef);
if (lockSnapshot.exists) {
// If the lock exists, check if we locked it
return lockSnapshot.data().executionId === executionId;
}
// If it doesn't exist, attempt to create it
await transaction.set(lockRef, {
executionId,
// The timestamp and lockedAt date are just for debugging, why not?
timestamp,
lockedAt: new Date(),
});
// If the write succeeds, we own the lock
return true;
});
if (locked !== true) {
throw new Error("Already locked. This pubsub event has already been serviced.");
}
console.log("Locked");
// Do important stuff
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment