Files
MikrotikManager/backend/src/services/speed-run-persistence.ts
T

43 lines
2.5 KiB
TypeScript

export interface SpeedProbeEndpoints { id: string; srcServerId: number; dstServerId: number }
export interface SpeedProbeContext extends SpeedProbeEndpoints {
srcInterface: string; dstInterface: string; protocol: "tcp" | "udp"; direction: "both" | "transmit" | "receive"; durationSec: number
}
export class SpeedProbeContextChanged extends Error {
constructor(message = "Параметры speed-пробы изменились. Обновите список проб перед запуском") { super(message) }
}
export class SpeedProbeEndpointsChanged extends SpeedProbeContextChanged {
constructor() { super("Пара устройств speed-пробы изменилась. Обновите список проб перед запуском") }
}
export function matchesSpeedProbeEndpoints(row: unknown, target: SpeedProbeEndpoints): boolean {
if (!row || typeof row !== "object") return false
const probe = row as Partial<SpeedProbeEndpoints>
return probe.id === target.id && probe.srcServerId === target.srcServerId && probe.dstServerId === target.dstServerId
}
export function assertSpeedProbeEndpoints(row: unknown, target: SpeedProbeEndpoints): void {
if (!matchesSpeedProbeEndpoints(row, target)) throw new SpeedProbeEndpointsChanged()
}
export function matchesSpeedProbeContext(row: unknown, target: SpeedProbeContext): boolean {
if (!matchesSpeedProbeEndpoints(row, target)) return false
const probe = row as Partial<SpeedProbeContext>
return probe.srcInterface === target.srcInterface && probe.dstInterface === target.dstInterface
&& probe.protocol === target.protocol && probe.direction === target.direction && probe.durationSec === target.durationSec
}
export function assertSpeedProbeContext(row: unknown, target: SpeedProbeContext): void {
assertSpeedProbeEndpoints(row, target)
if (!matchesSpeedProbeContext(row, target)) throw new SpeedProbeContextChanged()
}
/** Changed/deleted probes retain their snapshot; history keeps the actual run without a stale association. */
export async function persistSpeedRun<C, T extends SpeedProbeEndpoints = SpeedProbeEndpoints>(target: T | null, deps: {
transaction: (work: (context: C) => Promise<void>) => Promise<void>
updateProbe: (context: C, target: T) => Promise<boolean>
insertRun: (context: C, associatedProbeId: string | null) => Promise<void>
}): Promise<void> {
await deps.transaction(async context => {
const associated = target ? await deps.updateProbe(context, target) : false
await deps.insertRun(context, associated && target ? target.id : null)
})
}