First Commit
This commit is contained in:
43
src/database/lock.ts
Normal file
43
src/database/lock.ts
Normal file
@ -0,0 +1,43 @@
|
||||
export type Release = { release: () => void };
|
||||
|
||||
export default class PathLock {
|
||||
locks: {
|
||||
path: string[],
|
||||
next: (() => void)[]
|
||||
}[] = [];
|
||||
|
||||
constructor() { }
|
||||
|
||||
async lock(path: string[]) {
|
||||
let locks = this.locks.filter(lock => {
|
||||
let idxs = Math.min(lock.path.length, path.length);
|
||||
if (idxs === 0) return true;
|
||||
for (let i = 0; i < idxs; i++) {
|
||||
if (lock.path[i] !== path[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
|
||||
if (locks.length > 0) { // await till release
|
||||
await Promise.all(locks.map(l => new Promise(res => l.next.push(res))))
|
||||
} else {
|
||||
let lock = {
|
||||
path: path,
|
||||
next: []
|
||||
}
|
||||
this.locks.push(lock);
|
||||
locks = [lock];
|
||||
}
|
||||
|
||||
return () => {
|
||||
locks.forEach(lock => {
|
||||
if (lock.next.length > 0) {
|
||||
setImmediate(() => lock.next.shift()());
|
||||
} else {
|
||||
this.locks.splice(this.locks.indexOf(lock), 1);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user