mirror of https://github.com/jetkvm/kvm.git
[WIP] Optimizations: code readiness optimizations
This commit is contained in:
parent
8f17bbd1f9
commit
da85b54fc2
|
|
@ -146,8 +146,8 @@ const baseExtension = expectedRate + maxLateness // 100ms extension on perfect t
|
||||||
const maxStaleness = 225 * time.Millisecond // discard ancient packets outright
|
const maxStaleness = 225 * time.Millisecond // discard ancient packets outright
|
||||||
|
|
||||||
func handleHidRPCKeypressKeepAlive(session *Session) error {
|
func handleHidRPCKeypressKeepAlive(session *Session) error {
|
||||||
// Update LastActive to prevent session timeout (jiggler sends every 50ms)
|
// NOTE: Do NOT update LastActive here - jiggler keep-alives are automated,
|
||||||
sessionManager.UpdateLastActive(session.ID)
|
// not human input. Only actual keyboard/mouse input should prevent timeout.
|
||||||
|
|
||||||
session.keepAliveJitterLock.Lock()
|
session.keepAliveJitterLock.Lock()
|
||||||
defer session.keepAliveJitterLock.Unlock()
|
defer session.keepAliveJitterLock.Unlock()
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,9 @@ func initNative(systemVersion *semver.Version, appVersion *semver.Version) {
|
||||||
Str("sessionID", s.ID).
|
Str("sessionID", s.ID).
|
||||||
Err(err).
|
Err(err).
|
||||||
Msg("error writing sample to session")
|
Msg("error writing sample to session")
|
||||||
|
} else {
|
||||||
|
// Update LastActive when video frame successfully sent (prevents observer timeout)
|
||||||
|
sessionManager.UpdateLastActive(s.ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -84,10 +84,6 @@ type TransferBlacklistEntry struct {
|
||||||
var (
|
var (
|
||||||
lastBroadcast time.Time
|
lastBroadcast time.Time
|
||||||
broadcastMutex sync.Mutex
|
broadcastMutex sync.Mutex
|
||||||
|
|
||||||
// Pre-allocated event maps to reduce allocations
|
|
||||||
modePrimaryEvent = map[string]string{"mode": "primary"}
|
|
||||||
modeObserverEvent = map[string]string{"mode": "observer"}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SessionManager struct {
|
type SessionManager struct {
|
||||||
|
|
@ -413,18 +409,20 @@ func (sm *SessionManager) RemoveSession(sessionID string) {
|
||||||
// Only add grace period if this is NOT an intentional logout
|
// Only add grace period if this is NOT an intentional logout
|
||||||
if !isIntentionalLogout {
|
if !isIntentionalLogout {
|
||||||
// Limit grace period entries to prevent memory exhaustion
|
// Limit grace period entries to prevent memory exhaustion
|
||||||
|
// Evict the entry that will expire soonest (oldest expiration time)
|
||||||
for len(sm.reconnectGrace) >= maxGracePeriodEntries {
|
for len(sm.reconnectGrace) >= maxGracePeriodEntries {
|
||||||
var oldestID string
|
var evictID string
|
||||||
var oldestTime time.Time
|
var earliestExpiration time.Time
|
||||||
for id, graceTime := range sm.reconnectGrace {
|
for id, graceTime := range sm.reconnectGrace {
|
||||||
if oldestTime.IsZero() || graceTime.Before(oldestTime) {
|
// Find the grace period that expires first (earliest time)
|
||||||
oldestID = id
|
if earliestExpiration.IsZero() || graceTime.Before(earliestExpiration) {
|
||||||
oldestTime = graceTime
|
evictID = id
|
||||||
|
earliestExpiration = graceTime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if oldestID != "" {
|
if evictID != "" {
|
||||||
delete(sm.reconnectGrace, oldestID)
|
delete(sm.reconnectGrace, evictID)
|
||||||
delete(sm.reconnectInfo, oldestID)
|
delete(sm.reconnectInfo, evictID)
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -668,7 +666,7 @@ func (sm *SessionManager) RequestPrimary(sessionID string) error {
|
||||||
err := sm.transferPrimaryRole("", sessionID, "initial_promotion", "first session auto-promotion")
|
err := sm.transferPrimaryRole("", sessionID, "initial_promotion", "first session auto-promotion")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// Send mode change event after promoting
|
// Send mode change event after promoting
|
||||||
writeJSONRPCEvent("modeChanged", modePrimaryEvent, session)
|
writeJSONRPCEvent("modeChanged", map[string]string{"mode": "primary"}, session)
|
||||||
go sm.broadcastSessionListUpdate()
|
go sm.broadcastSessionListUpdate()
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
|
@ -755,7 +753,7 @@ func (sm *SessionManager) ReleasePrimary(sessionID string) error {
|
||||||
// Send mode change event for promoted session
|
// Send mode change event for promoted session
|
||||||
go func() {
|
go func() {
|
||||||
if promotedSession := sessionManager.GetSession(promotedSessionID); promotedSession != nil {
|
if promotedSession := sessionManager.GetSession(promotedSessionID); promotedSession != nil {
|
||||||
writeJSONRPCEvent("modeChanged", modePrimaryEvent, promotedSession)
|
writeJSONRPCEvent("modeChanged", map[string]string{"mode": "primary"}, promotedSession)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -797,13 +795,13 @@ func (sm *SessionManager) TransferPrimary(fromID, toID string) error {
|
||||||
// Send events in goroutines to avoid holding lock
|
// Send events in goroutines to avoid holding lock
|
||||||
go func() {
|
go func() {
|
||||||
if fromSession := sessionManager.GetSession(fromID); fromSession != nil {
|
if fromSession := sessionManager.GetSession(fromID); fromSession != nil {
|
||||||
writeJSONRPCEvent("modeChanged", modeObserverEvent, fromSession)
|
writeJSONRPCEvent("modeChanged", map[string]string{"mode": "observer"}, fromSession)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if toSession := sessionManager.GetSession(toID); toSession != nil {
|
if toSession := sessionManager.GetSession(toID); toSession != nil {
|
||||||
writeJSONRPCEvent("modeChanged", modePrimaryEvent, toSession)
|
writeJSONRPCEvent("modeChanged", map[string]string{"mode": "primary"}, toSession)
|
||||||
}
|
}
|
||||||
sm.broadcastSessionListUpdate()
|
sm.broadcastSessionListUpdate()
|
||||||
}()
|
}()
|
||||||
|
|
@ -861,13 +859,13 @@ func (sm *SessionManager) ApprovePrimaryRequest(currentPrimaryID, requesterID st
|
||||||
// Send events after releasing lock to avoid deadlock
|
// Send events after releasing lock to avoid deadlock
|
||||||
go func() {
|
go func() {
|
||||||
if demotedSession := sessionManager.GetSession(currentPrimaryID); demotedSession != nil {
|
if demotedSession := sessionManager.GetSession(currentPrimaryID); demotedSession != nil {
|
||||||
writeJSONRPCEvent("modeChanged", modeObserverEvent, demotedSession)
|
writeJSONRPCEvent("modeChanged", map[string]string{"mode": "observer"}, demotedSession)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if promotedSession := sessionManager.GetSession(requesterID); promotedSession != nil {
|
if promotedSession := sessionManager.GetSession(requesterID); promotedSession != nil {
|
||||||
writeJSONRPCEvent("modeChanged", modePrimaryEvent, promotedSession)
|
writeJSONRPCEvent("modeChanged", map[string]string{"mode": "primary"}, promotedSession)
|
||||||
}
|
}
|
||||||
sm.broadcastSessionListUpdate()
|
sm.broadcastSessionListUpdate()
|
||||||
}()
|
}()
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,6 @@ export default function Actionbar({
|
||||||
const response = JSON.parse(event.data);
|
const response = JSON.parse(event.data);
|
||||||
if (response.id === id && response.result) {
|
if (response.id === id && response.result) {
|
||||||
setSessions(response.result);
|
setSessions(response.result);
|
||||||
rpcDataChannel.removeEventListener("message", handler);
|
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Ignore parse errors for non-JSON messages
|
// Ignore parse errors for non-JSON messages
|
||||||
|
|
@ -62,10 +61,14 @@ export default function Actionbar({
|
||||||
rpcDataChannel.addEventListener("message", handler);
|
rpcDataChannel.addEventListener("message", handler);
|
||||||
rpcDataChannel.send(message);
|
rpcDataChannel.send(message);
|
||||||
|
|
||||||
// Clean up after timeout
|
const timeoutId = setTimeout(() => {
|
||||||
setTimeout(() => {
|
|
||||||
rpcDataChannel.removeEventListener("message", handler);
|
rpcDataChannel.removeEventListener("message", handler);
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
rpcDataChannel.removeEventListener("message", handler);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}, [rpcDataChannel, sessions.length, setSessions]);
|
}, [rpcDataChannel, sessions.length, setSessions]);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue