40 lines
862 B
JavaScript
40 lines
862 B
JavaScript
/**
|
|
* Async lock utility - Promise-based mutex per key.
|
|
* Ensures only one async operation executes per key at a time.
|
|
*/
|
|
|
|
const locks = new Map()
|
|
|
|
/**
|
|
* Acquire a lock for a key and execute callback.
|
|
* Only one callback per key executes at a time.
|
|
* @param {string} key - Lock key
|
|
* @param {Function} callback - Async function to execute
|
|
* @returns {Promise<any>} Result of callback
|
|
*/
|
|
export async function acquire(key, callback) {
|
|
const lockKey = String(key)
|
|
let queue = locks.get(lockKey)
|
|
|
|
if (!queue) {
|
|
queue = Promise.resolve()
|
|
locks.set(lockKey, queue)
|
|
}
|
|
|
|
const next = queue.then(() => callback()).finally(() => {
|
|
if (locks.get(lockKey) === next) {
|
|
locks.delete(lockKey)
|
|
}
|
|
})
|
|
|
|
locks.set(lockKey, next)
|
|
return next
|
|
}
|
|
|
|
/**
|
|
* Clear all locks (for testing).
|
|
*/
|
|
export function clearLocks() {
|
|
locks.clear()
|
|
}
|