mirror of https://github.com/jetkvm/kvm.git
fix: reduce observer promotion delay from ~40s to ~11s
1. Terminal access permission check: - Add Permission.TERMINAL_ACCESS check to Web Terminal button - Prevents observer sessions from accessing terminal 2. Immediate websocket cleanup: - Close peer connection immediately when websocket errors - Previously waited 24+ seconds for ICE to transition from disconnected to failed - Now triggers session cleanup immediately on tab close 3. Immediate grace period validation: - Trigger validateSinglePrimary() immediately when grace period expires - Previously waited up to 10 seconds for next periodic validation - Eliminates unnecessary delay in observer promotion Timeline improvement: Before: Tab close → 6s (ICE disconnect) → 24s (ICE fail) → RemoveSession → 10s grace → up to 10s validation = ~50s total After: Tab close → immediate peerConnection.Close() → immediate RemoveSession → 10s grace → immediate validation = ~11s total
This commit is contained in:
parent
7901677551
commit
b388bc3c62
|
|
@ -1520,9 +1520,11 @@ func (sm *SessionManager) cleanupInactiveSessions(ctx context.Context) {
|
||||||
needsBroadcast := false
|
needsBroadcast := false
|
||||||
|
|
||||||
// Check for expired grace periods and promote if needed
|
// Check for expired grace periods and promote if needed
|
||||||
|
gracePeriodExpired := false
|
||||||
for sessionID, graceTime := range sm.reconnectGrace {
|
for sessionID, graceTime := range sm.reconnectGrace {
|
||||||
if now.After(graceTime) {
|
if now.After(graceTime) {
|
||||||
delete(sm.reconnectGrace, sessionID)
|
delete(sm.reconnectGrace, sessionID)
|
||||||
|
gracePeriodExpired = true
|
||||||
|
|
||||||
wasHoldingPrimarySlot := (sm.lastPrimaryID == sessionID)
|
wasHoldingPrimarySlot := (sm.lastPrimaryID == sessionID)
|
||||||
|
|
||||||
|
|
@ -1735,12 +1737,18 @@ func (sm *SessionManager) cleanupInactiveSessions(ctx context.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Periodic validateSinglePrimary to catch deadlock states
|
// Run validation immediately if a grace period expired, otherwise run periodically
|
||||||
validationCounter++
|
if gracePeriodExpired {
|
||||||
if validationCounter >= 10 { // Every 10 seconds
|
sm.logger.Debug().Msg("Running immediate validation after grace period expiration")
|
||||||
validationCounter = 0
|
|
||||||
sm.logger.Debug().Msg("Running periodic session validation to catch deadlock states")
|
|
||||||
sm.validateSinglePrimary()
|
sm.validateSinglePrimary()
|
||||||
|
} else {
|
||||||
|
// Periodic validateSinglePrimary to catch deadlock states
|
||||||
|
validationCounter++
|
||||||
|
if validationCounter >= 10 { // Every 10 seconds
|
||||||
|
validationCounter = 0
|
||||||
|
sm.logger.Debug().Msg("Running periodic session validation to catch deadlock states")
|
||||||
|
sm.validateSinglePrimary()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sm.mu.Unlock()
|
sm.mu.Unlock()
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ export default function Actionbar({
|
||||||
className="flex flex-wrap items-center justify-between gap-x-4 gap-y-2 py-1.5"
|
className="flex flex-wrap items-center justify-between gap-x-4 gap-y-2 py-1.5"
|
||||||
>
|
>
|
||||||
<div className="relative flex flex-wrap items-center gap-x-2 gap-y-2">
|
<div className="relative flex flex-wrap items-center gap-x-2 gap-y-2">
|
||||||
{developerMode && (
|
{developerMode && hasPermission(Permission.TERMINAL_ACCESS) && (
|
||||||
<Button
|
<Button
|
||||||
size="XS"
|
size="XS"
|
||||||
theme="light"
|
theme="light"
|
||||||
|
|
|
||||||
7
web.go
7
web.go
|
|
@ -357,6 +357,13 @@ func handleWebRTCSignalWsMessages(
|
||||||
typ, msg, err := wsCon.Read(runCtx)
|
typ, msg, err := wsCon.Read(runCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Warn().Str("error", err.Error()).Msg("websocket read error")
|
l.Warn().Str("error", err.Error()).Msg("websocket read error")
|
||||||
|
// Clean up session when websocket closes
|
||||||
|
if session := sessionManager.GetSession(connectionID); session != nil && session.peerConnection != nil {
|
||||||
|
l.Info().
|
||||||
|
Str("sessionID", session.ID).
|
||||||
|
Msg("Closing peer connection due to websocket error")
|
||||||
|
_ = session.peerConnection.Close()
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if typ != websocket.MessageText {
|
if typ != websocket.MessageText {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue