fix(api): дождаться запросов перед операцией с базой
This commit is contained in:
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) }
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user