fix(server): apply lifecycle reply state optimistically (heartbeat lag)
The agent reply is authoritative for the action just taken; the fleet DB only updates on the next heartbeat (~10s), so the immediate refetch read a stale state and reverted the UI (Start -> still Stopped). Now apply the reply's state/uptime directly to the instance. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -68,8 +68,10 @@ export const useInstancesStore = defineStore('instances', () => {
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a lifecycle command to the current instance. Returns the agent's
|
||||
* reply (which carries the new state); refetches so the list reflects it.
|
||||
* Send a lifecycle command to the current instance and apply the agent's
|
||||
* reply state OPTIMISTICALLY. The reply is authoritative for the action just
|
||||
* taken; the fleet DB only catches up on the next heartbeat (~10s), so an
|
||||
* immediate refetch would read a stale state and clobber the result.
|
||||
* Throws on failure so the view can toast.
|
||||
*/
|
||||
async function lifecycle(action: LifecycleAction): Promise<Record<string, unknown>> {
|
||||
@@ -78,13 +80,26 @@ export const useInstancesStore = defineStore('instances', () => {
|
||||
acting.value = action
|
||||
try {
|
||||
const res = await api.post<Record<string, unknown>>(`/instances/${id}/lifecycle`, { action })
|
||||
await fetchInstances()
|
||||
applyReplyState(id, res)
|
||||
return res
|
||||
} finally {
|
||||
acting.value = null
|
||||
}
|
||||
}
|
||||
|
||||
/** Update an instance's state/uptime from a lifecycle/status reply. */
|
||||
function applyReplyState(id: string, res: Record<string, unknown>): void {
|
||||
if ((res as { status?: string }).status !== 'success') return
|
||||
const stateObj = (res as { state?: { state?: string } }).state
|
||||
const newState = stateObj?.state
|
||||
const inst = instances.value.find((i) => i.id === id)
|
||||
if (inst && typeof newState === 'string') {
|
||||
inst.state = newState
|
||||
const up = (res as { uptime_seconds?: number }).uptime_seconds
|
||||
inst.uptime_seconds = typeof up === 'number' ? up : newState === 'running' ? inst.uptime_seconds : 0
|
||||
}
|
||||
}
|
||||
|
||||
async function rcon(command: string): Promise<Record<string, unknown>> {
|
||||
const id = currentId.value
|
||||
if (!id) throw new Error('No instance selected')
|
||||
|
||||
Reference in New Issue
Block a user