Fix konzola: race condition PTY + logging start/finish

- Ne briše ptySess iz sesije po završetku — WS handler ga koristi za replay
- WS handler šalje close frame kad proces završi
- Logovanje: PTY spawned (PID) + PTY finished (status)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
djuka 2026-02-20 15:48:00 +00:00
parent 64df1e784c
commit fa8aa59b29
2 changed files with 11 additions and 3 deletions

View File

@ -3,6 +3,7 @@ package server
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"os/exec"
@ -157,9 +158,11 @@ func cleanEnv() []string {
func (s *Server) runCommand(session *sessionState, command, execID string) {
ptySess, err := spawnConsolePTY(s.projectRoot(), command)
if err != nil {
log.Printf("PTY spawn error for %s: %v", execID, err)
s.finishSession(session, execID, "error")
return
}
log.Printf("PTY spawned for %s (PID %d)", execID, ptySess.Cmd.Process.Pid)
session.mu.Lock()
session.cmd = ptySess.Cmd
@ -173,10 +176,11 @@ func (s *Server) runCommand(session *sessionState, command, execID string) {
if ptySess.Cmd.ProcessState != nil && !ptySess.Cmd.ProcessState.Success() {
status = "error"
}
log.Printf("PTY finished for %s (status: %s)", execID, status)
session.mu.Lock()
session.ptySess = nil
session.mu.Unlock()
// Note: we do NOT clear session.ptySess here — the WS handler
// needs it for replay buffer even after the process exits.
// It gets replaced when a new command starts.
s.finishSession(session, execID, status)
}

View File

@ -113,6 +113,10 @@ connected:
case writeCh <- []byte("\r\n\033[33m[Sesija završena]\033[0m\r\n"):
default:
}
// Give browser time to receive the message, then close
time.Sleep(500 * time.Millisecond)
conn.WriteMessage(websocket.CloseMessage,
websocket.FormatCloseMessage(websocket.CloseNormalClosure, "done"))
}()
// WebSocket → PTY (read pump)