diff --git a/cmd/mosh-wasm/main.go b/cmd/mosh-wasm/main.go index 8b74902..72ec297 100644 --- a/cmd/mosh-wasm/main.go +++ b/cmd/mosh-wasm/main.go @@ -158,7 +158,8 @@ func (s *session) recvLoop() { t := s.client.Transport() oldNum := t.LastRecvOldNum() newNum := t.LastRecvNewNum() - s.tracker.applyDiff(diff, oldNum, newNum) + throwawayNum := t.ThrowawayNum() + s.tracker.applyDiff(diff, oldNum, newNum, throwawayNum) } } diff --git a/cmd/mosh-wasm/state.go b/cmd/mosh-wasm/state.go index 0370261..d5931ed 100644 --- a/cmd/mosh-wasm/state.go +++ b/cmd/mosh-wasm/state.go @@ -41,7 +41,8 @@ func newStateTracker(cols, rows int) *stateTracker { } // applyDiff processes an incoming server diff using state tracking. -func (st *stateTracker) applyDiff(diff []byte, oldNum, newNum uint64) { +// throwawayNum is the server's indication of which states it no longer references. +func (st *stateTracker) applyDiff(diff []byte, oldNum, newNum, throwawayNum uint64) { st.mu.Lock() defer st.mu.Unlock() @@ -93,9 +94,13 @@ func (st *stateTracker) applyDiff(diff []byte, oldNum, newNum uint64) { st.latestState = newNum } - // Bound states list. - if len(st.states) > 128 { - st.pruneStates() + // Prune states the server no longer references. + if throwawayNum > 0 { + for n := range st.states { + if n < throwawayNum { + delete(st.states, n) + } + } } // Display diff: compute ANSI difference between displayed and latest. @@ -133,24 +138,3 @@ func (st *stateTracker) resize(cols, rows int) { st.displayedFB = nil } -func (st *stateTracker) pruneStates() { - if len(st.states) <= 64 { - return - } - // Keep the 64 most recent states. - var nums []uint64 - for n := range st.states { - nums = append(nums, n) - } - // Simple sort for small lists. - for i := range nums { - for j := i + 1; j < len(nums); j++ { - if nums[j] < nums[i] { - nums[i], nums[j] = nums[j], nums[i] - } - } - } - for _, n := range nums[:len(nums)-64] { - delete(st.states, n) - } -} diff --git a/transport.go b/transport.go index 0a03b7b..347dd74 100644 --- a/transport.go +++ b/transport.go @@ -379,6 +379,14 @@ func (t *Transport) LastRecvNewNum() uint64 { return t.lastRecvNewNum } +// ThrowawayNum returns the server's throwaway number — states below this +// are no longer referenced by the server and can be safely pruned. +func (t *Transport) ThrowawayNum() uint64 { + t.mu.Lock() + defer t.mu.Unlock() + return t.throwawayNum +} + // LastRecv returns the time of the last received datagram. func (t *Transport) LastRecv() time.Time { t.mu.Lock()