mirror of
https://github.com/wu736139669/hapi.git
synced 2026-11-12 02:28:05 +00:00
refactor(api): extract versioned update handling to shared utility
Extract duplicate version acknowledgment logic from apiMachine and apiSession into a reusable applyVersionedAck utility. This handles success, version-mismatch, and error responses consistently with customizable parsing and error handling via options object.
This commit is contained in:
+41
-86
@@ -12,6 +12,7 @@ import { backoff } from '@/utils/time'
|
||||
import { RpcHandlerManager } from './rpc/RpcHandlerManager'
|
||||
import { registerCommonHandlers } from '../modules/common/registerCommonHandlers'
|
||||
import type { SpawnSessionOptions, SpawnSessionResult } from '../modules/common/rpcTypes'
|
||||
import { applyVersionedAck } from './versionedUpdate'
|
||||
|
||||
interface ServerToDaemonEvents {
|
||||
update: (data: Update) => void
|
||||
@@ -157,49 +158,26 @@ export class ApiMachineClient {
|
||||
expectedVersion: this.machine.metadataVersion
|
||||
}) as unknown
|
||||
|
||||
if (!answer || typeof answer !== 'object') {
|
||||
throw new Error('Invalid machine-update-metadata response')
|
||||
}
|
||||
|
||||
const obj = answer as { result?: unknown; version?: unknown; metadata?: unknown }
|
||||
if (obj.result === 'success' && typeof obj.version === 'number') {
|
||||
const next = obj.metadata
|
||||
if (next == null) {
|
||||
this.machine.metadata = null
|
||||
} else {
|
||||
const parsed = MachineMetadataSchema.safeParse(next)
|
||||
if (parsed.success) {
|
||||
this.machine.metadata = parsed.data
|
||||
} else {
|
||||
logger.debug('[API MACHINE] Ignoring invalid metadata value from ack', { version: obj.version })
|
||||
}
|
||||
}
|
||||
this.machine.metadataVersion = obj.version
|
||||
return
|
||||
}
|
||||
|
||||
if (obj.result === 'version-mismatch' && typeof obj.version === 'number') {
|
||||
const next = obj.metadata
|
||||
if (next == null) {
|
||||
this.machine.metadata = null
|
||||
} else {
|
||||
const parsed = MachineMetadataSchema.safeParse(next)
|
||||
if (parsed.success) {
|
||||
this.machine.metadata = parsed.data
|
||||
} else {
|
||||
logger.debug('[API MACHINE] Ignoring invalid metadata value from version-mismatch ack', { version: obj.version })
|
||||
}
|
||||
}
|
||||
this.machine.metadataVersion = obj.version
|
||||
throw new Error('Metadata version mismatch')
|
||||
}
|
||||
|
||||
if (obj.result === 'error') {
|
||||
const reason = typeof (obj as { reason?: unknown }).reason === 'string'
|
||||
? (obj as { reason?: string }).reason
|
||||
: 'unknown'
|
||||
throw new Error(`Machine metadata update failed (${reason})`)
|
||||
}
|
||||
applyVersionedAck(answer, {
|
||||
valueKey: 'metadata',
|
||||
parseValue: (value) => {
|
||||
const parsed = MachineMetadataSchema.safeParse(value)
|
||||
return parsed.success ? parsed.data : null
|
||||
},
|
||||
applyValue: (value) => {
|
||||
this.machine.metadata = value
|
||||
},
|
||||
applyVersion: (version) => {
|
||||
this.machine.metadataVersion = version
|
||||
},
|
||||
logInvalidValue: (context, version) => {
|
||||
const suffix = context === 'success' ? 'ack' : 'version-mismatch ack'
|
||||
logger.debug(`[API MACHINE] Ignoring invalid metadata value from ${suffix}`, { version })
|
||||
},
|
||||
invalidResponseMessage: 'Invalid machine-update-metadata response',
|
||||
errorMessage: 'Machine metadata update failed',
|
||||
versionMismatchMessage: 'Metadata version mismatch'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -213,49 +191,26 @@ export class ApiMachineClient {
|
||||
expectedVersion: this.machine.daemonStateVersion
|
||||
}) as unknown
|
||||
|
||||
if (!answer || typeof answer !== 'object') {
|
||||
throw new Error('Invalid machine-update-state response')
|
||||
}
|
||||
|
||||
const obj = answer as { result?: unknown; version?: unknown; daemonState?: unknown }
|
||||
if (obj.result === 'success' && typeof obj.version === 'number') {
|
||||
const next = obj.daemonState
|
||||
if (next == null) {
|
||||
this.machine.daemonState = null
|
||||
} else {
|
||||
const parsed = DaemonStateSchema.safeParse(next)
|
||||
if (parsed.success) {
|
||||
this.machine.daemonState = parsed.data
|
||||
} else {
|
||||
logger.debug('[API MACHINE] Ignoring invalid daemonState value from ack', { version: obj.version })
|
||||
}
|
||||
}
|
||||
this.machine.daemonStateVersion = obj.version
|
||||
return
|
||||
}
|
||||
|
||||
if (obj.result === 'version-mismatch' && typeof obj.version === 'number') {
|
||||
const next = obj.daemonState
|
||||
if (next == null) {
|
||||
this.machine.daemonState = null
|
||||
} else {
|
||||
const parsed = DaemonStateSchema.safeParse(next)
|
||||
if (parsed.success) {
|
||||
this.machine.daemonState = parsed.data
|
||||
} else {
|
||||
logger.debug('[API MACHINE] Ignoring invalid daemonState value from version-mismatch ack', { version: obj.version })
|
||||
}
|
||||
}
|
||||
this.machine.daemonStateVersion = obj.version
|
||||
throw new Error('Daemon state version mismatch')
|
||||
}
|
||||
|
||||
if (obj.result === 'error') {
|
||||
const reason = typeof (obj as { reason?: unknown }).reason === 'string'
|
||||
? (obj as { reason?: string }).reason
|
||||
: 'unknown'
|
||||
throw new Error(`Machine state update failed (${reason})`)
|
||||
}
|
||||
applyVersionedAck(answer, {
|
||||
valueKey: 'daemonState',
|
||||
parseValue: (value) => {
|
||||
const parsed = DaemonStateSchema.safeParse(value)
|
||||
return parsed.success ? parsed.data : null
|
||||
},
|
||||
applyValue: (value) => {
|
||||
this.machine.daemonState = value
|
||||
},
|
||||
applyVersion: (version) => {
|
||||
this.machine.daemonStateVersion = version
|
||||
},
|
||||
logInvalidValue: (context, version) => {
|
||||
const suffix = context === 'success' ? 'ack' : 'version-mismatch ack'
|
||||
logger.debug(`[API MACHINE] Ignoring invalid daemonState value from ${suffix}`, { version })
|
||||
},
|
||||
invalidResponseMessage: 'Invalid machine-update-state response',
|
||||
errorMessage: 'Machine state update failed',
|
||||
versionMismatchMessage: 'Daemon state version mismatch'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user