fix(pi): reiniciar en modo Linux vuelve a arrancar el guest

connect() se rendia si el socket no estaba CLOSED, y uno en CLOSING pasa
esa prueba: pulsar "Linux terminal" justo despues de una ejecucion
cerraba el socket y el arranque siguiente no hacia nada -- ni guest, ni
error, y la barra seguia mostrando Stop. Ahora solo se rinde con OPEN o
CONNECTING y descarta el que se esta cerrando.

startBoard marca ademas running en la rama Pi: el boton de Linux
reinicia la placa por su cuenta, sin pasar por la barra, asi que el flag
se quedaba con lo que hubiera dejado la ejecucion anterior.
This commit is contained in:
David Montero Crespo 2026-07-29 19:33:14 +02:00
parent c55e399055
commit 6bfeaf1b15
2 changed files with 15 additions and 2 deletions

View File

@ -105,7 +105,13 @@ export class RaspberryPi3Bridge {
}
connect(): void {
if (this.socket && this.socket.readyState !== WebSocket.CLOSED) return;
const state = this.socket?.readyState;
if (state === WebSocket.OPEN || state === WebSocket.CONNECTING) return;
// A socket in CLOSING is on its way out, not usable: the old guard
// treated it as live and returned, so "restart in Linux mode" right
// after a run silently did nothing — no boot, and the toolbar still
// showing Stop. Drop it and open a fresh one.
this.socket = null;
const base = API_BASE();
const wsProtocol = base.startsWith('https') ? 'wss:' : 'ws:';

View File

@ -1929,11 +1929,18 @@ export const useSimulatorStore = create<SimulatorState>((set, get) => {
// booting a Linux guest (a backend process + ~90 s). The detector
// lives in the overlay; `enginePinned` lets the user override it.
const decision = decideEngine(boardId, board.enginePinned);
// `running` is set here (not only by the toolbar): the Linux-mode
// button restarts the board directly, and without this the flag
// kept whatever the previous run left, so the UI showed Stop for
// a board that was not running.
set((s) => ({
boards: s.boards.map((b) =>
b.id === boardId ? { ...b, engineMode: decision.engine } : b,
b.id === boardId
? { ...b, engineMode: decision.engine, running: true }
: b,
),
serialMonitorOpen: true,
...(s.activeBoardId === boardId ? { running: true } : {}),
}));
if (decision.engine === 'instant') {
const instant = getInstantEngine();