mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-04-01 06:42:26 +00:00
62 lines
1.4 KiB
TypeScript
62 lines
1.4 KiB
TypeScript
import { Instance } from "../project/instance"
|
|
import { Log } from "../util/log"
|
|
|
|
export namespace Scheduler {
|
|
const log = Log.create({ service: "scheduler" })
|
|
|
|
export type Task = {
|
|
id: string
|
|
interval: number
|
|
run: () => Promise<void>
|
|
scope?: "instance" | "global"
|
|
}
|
|
|
|
type Timer = ReturnType<typeof setInterval>
|
|
type Entry = {
|
|
tasks: Map<string, Task>
|
|
timers: Map<string, Timer>
|
|
}
|
|
|
|
const create = (): Entry => {
|
|
const tasks = new Map<string, Task>()
|
|
const timers = new Map<string, Timer>()
|
|
return { tasks, timers }
|
|
}
|
|
|
|
const shared = create()
|
|
|
|
const state = Instance.state(
|
|
() => create(),
|
|
async (entry) => {
|
|
for (const timer of entry.timers.values()) {
|
|
clearInterval(timer)
|
|
}
|
|
entry.tasks.clear()
|
|
entry.timers.clear()
|
|
},
|
|
)
|
|
|
|
export function register(task: Task) {
|
|
const scope = task.scope ?? "instance"
|
|
const entry = scope === "global" ? shared : state()
|
|
const current = entry.timers.get(task.id)
|
|
if (current && scope === "global") return
|
|
if (current) clearInterval(current)
|
|
|
|
entry.tasks.set(task.id, task)
|
|
void run(task)
|
|
const timer = setInterval(() => {
|
|
void run(task)
|
|
}, task.interval)
|
|
timer.unref()
|
|
entry.timers.set(task.id, timer)
|
|
}
|
|
|
|
async function run(task: Task) {
|
|
log.info("run", { id: task.id })
|
|
await task.run().catch((error) => {
|
|
log.error("run failed", { id: task.id, error })
|
|
})
|
|
}
|
|
}
|