Support automatically creating recurring events

Also implement locks for tasks that can have unintended side-effects if ran simultaneously.

Other minor UI tweaks.
This commit is contained in:
Bruno Bernardino
2024-03-31 13:19:13 +01:00
parent d3a6f60d81
commit 321341a2fb
10 changed files with 312 additions and 105 deletions

36
lib/interfaces/locker.ts Normal file
View File

@@ -0,0 +1,36 @@
// This is a simple, in-memory lock, which works well enough if you're serving from a single source/server
function wait(milliseconds = 100) {
return new Promise((resolve) => setTimeout(() => resolve(true), milliseconds));
}
const expirationInMilliseconds = 15 * 1000;
const locks: Map<string, { expiresAt: Date }> = new Map();
export default class Locker {
protected lockName: string = '';
constructor(lockName: string) {
this.lockName = lockName;
}
public async acquire() {
const currentLock = locks.get(this.lockName);
while (currentLock) {
// Only wait if the lock hasn't expired
if (currentLock.expiresAt > new Date()) {
await wait();
}
}
locks.set(this.lockName, {
expiresAt: new Date(new Date().setMilliseconds(new Date().getMilliseconds() + expirationInMilliseconds)),
});
}
public release() {
locks.delete(this.lockName);
}
}