fix(api): дождаться запросов перед операцией с базой

This commit is contained in:
Denozordec committed 2026-10-07 23:00:39 +07:00
1 parent 9264b6636a
commit 8682f2a7a5
12 files changed
+183 -5

No files matched your search

@@ -0,0 +1,31 @@
import type { FastifyInstance, FastifyRequest } from "fastify"
import { DatabaseRequestGate } from "../services/database-request-gate.js"
const streams = new WeakMap<FastifyRequest, { cancelled: boolean; abort?: () => void }>()
export function registerDatabaseStreamAbort(request: FastifyRequest, abort: () => void): void {
const state = streams.get(request)
if (!state) return
state.abort = abort
if (state.cancelled) abort()
}
export function installDatabaseRequestGate(app: FastifyInstance): void {
const gate = new DatabaseRequestGate()
app.addHook("onRoute", options => {
const path = options.url
if (!path.startsWith("/api/") || path === "/api/auth/config") return
const original = options.handler
const operation = path === "/api/system/database/backup" || path === "/api/system/database/restore"
const stream = path === "/api/traffic/flow/live" || /^\/api\/traffic\/servers\/:id\/live$/.test(path)
options.handler = async function (request, reply) {
const run = async () => await original.call(this, request, reply)
if (operation) return gate.exclusive(run)
if (!stream) return gate.request(run)
const state = { cancelled: false, abort: undefined as (() => void) | undefined }
streams.set(request, state)
try {
return await gate.request(run, () => { state.cancelled = true; state.abort?.() })
} finally { streams.delete(request) }
}
})
}