mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-07 01:47:47 +08:00
fix(usage): bound terminal event persistence
Add end-to-end terminal admission, bounded database fallback, and observable overload handling. Preserve first-byte lifecycle state across asynchronous runtime and frontend updates.
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import type { UsageRecord } from '../../types'
|
||||
import { syncUsageRecordStreamResolution } from '../recordSync'
|
||||
import {
|
||||
mergeUsageRecordFirstByteTimeMs,
|
||||
syncUsageRecordStreamResolution,
|
||||
} from '../recordSync'
|
||||
|
||||
function buildUsageRecord(overrides: Partial<UsageRecord> = {}): UsageRecord {
|
||||
return {
|
||||
@@ -59,3 +62,16 @@ describe('syncUsageRecordStreamResolution', () => {
|
||||
expect(nextRecords).toBe(records)
|
||||
})
|
||||
})
|
||||
|
||||
describe('mergeUsageRecordFirstByteTimeMs', () => {
|
||||
it('does not let a stale active update clear or reduce a resolved first-byte time', () => {
|
||||
expect(mergeUsageRecordFirstByteTimeMs(500, null)).toBe(500)
|
||||
expect(mergeUsageRecordFirstByteTimeMs(500, 320)).toBe(500)
|
||||
expect(mergeUsageRecordFirstByteTimeMs(500, 640)).toBe(640)
|
||||
expect(mergeUsageRecordFirstByteTimeMs(undefined, 320)).toBe(320)
|
||||
expect(mergeUsageRecordFirstByteTimeMs(undefined, 0)).toBe(0)
|
||||
expect(mergeUsageRecordFirstByteTimeMs(0, null)).toBe(0)
|
||||
expect(mergeUsageRecordFirstByteTimeMs(null, -1)).toBeNull()
|
||||
expect(mergeUsageRecordFirstByteTimeMs(-1, null)).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -78,6 +78,11 @@ describe('usage status helpers', () => {
|
||||
status: 'streaming',
|
||||
first_byte_time_ms: 320,
|
||||
}))).toBe('streaming')
|
||||
|
||||
expect(resolveDisplayRequestStatus(buildUsageRecord({
|
||||
status: 'streaming',
|
||||
first_byte_time_ms: 0,
|
||||
}))).toBe('streaming')
|
||||
})
|
||||
|
||||
it('treats active lifecycle records with failure signals as failed for display', () => {
|
||||
|
||||
@@ -5,6 +5,30 @@ export type UsageRecordStreamResolution = Pick<
|
||||
'id' | 'is_stream' | 'upstream_is_stream' | 'client_requested_stream' | 'client_is_stream'
|
||||
>
|
||||
|
||||
export function mergeUsageRecordFirstByteTimeMs(
|
||||
existingValue: number | null | undefined,
|
||||
nextValue: number | null | undefined
|
||||
): number | null | undefined {
|
||||
// Millisecond timing is floored, so 0 still means the first byte was observed.
|
||||
const existingIsResolved = typeof existingValue === 'number' &&
|
||||
Number.isFinite(existingValue) &&
|
||||
existingValue >= 0
|
||||
const nextIsResolved = typeof nextValue === 'number' &&
|
||||
Number.isFinite(nextValue) &&
|
||||
nextValue >= 0
|
||||
|
||||
if (existingIsResolved && nextIsResolved) {
|
||||
return Math.max(existingValue, nextValue)
|
||||
}
|
||||
if (existingIsResolved) {
|
||||
return existingValue
|
||||
}
|
||||
if (nextIsResolved) {
|
||||
return nextValue
|
||||
}
|
||||
return existingValue == null ? existingValue : undefined
|
||||
}
|
||||
|
||||
export function syncUsageRecordStreamResolution(
|
||||
records: UsageRecord[],
|
||||
resolved: UsageRecordStreamResolution
|
||||
|
||||
Reference in New Issue
Block a user