Preserve restored screen during ticket reattach
ci / test (push) Waiting to run
ci / fuzz-smoke (push) Waiting to run
ci / windows-client (push) Waiting to run
ci / package-release (linux-x86_64, ubuntu-latest) (push) Waiting to run
ci / package-release (macos-aarch64, macos-14) (push) Waiting to run
ci / package-release (macos-x86_64, macos-13) (push) Waiting to run
ci / package-release (windows-x86_64, windows-latest) (push) Waiting to run
ci / publish-gitea-release (push) Blocked by required conditions
ci / remote-bench (push) Waiting to run
ci / test (push) Waiting to run
ci / fuzz-smoke (push) Waiting to run
ci / windows-client (push) Waiting to run
ci / package-release (linux-x86_64, ubuntu-latest) (push) Waiting to run
ci / package-release (macos-aarch64, macos-14) (push) Waiting to run
ci / package-release (macos-x86_64, macos-13) (push) Waiting to run
ci / package-release (windows-x86_64, windows-latest) (push) Waiting to run
ci / publish-gitea-release (push) Blocked by required conditions
ci / remote-bench (push) Waiting to run
This commit is contained in:
+23
-2
@@ -813,6 +813,10 @@ fn attach_snapshot(session: &Session, cols: u16, rows: u16) -> Vec<u8> {
|
||||
screen_snapshot(session.parser.screen())
|
||||
}
|
||||
|
||||
fn restored_screen_is_pending_reattach(session: &Session) -> bool {
|
||||
session.restored_screen.is_some()
|
||||
}
|
||||
|
||||
fn mode_allows_terminal_updates(mode: &str) -> bool {
|
||||
mode != "view-only" && mode != "forward-only"
|
||||
}
|
||||
@@ -3707,7 +3711,7 @@ async fn broadcast_output(
|
||||
// short wall-clock age so low-throughput prompt/TUI changes persist
|
||||
// quickly while large bursts still avoid per-packet disk writes. The
|
||||
// actual file write happens after the lock is dropped.
|
||||
if session.persistent {
|
||||
if session.persistent && !restored_screen_is_pending_reattach(session) {
|
||||
session.bytes_since_persist = session
|
||||
.bytes_since_persist
|
||||
.saturating_add(output.bytes.len());
|
||||
@@ -4060,7 +4064,10 @@ fn flush_persistent_screens(state: &Arc<Mutex<ServerState>>) {
|
||||
let sessions_dir = locked.sessions_dir();
|
||||
let mut to_write: Vec<(String, u16, u16, u64, Vec<u8>)> = Vec::new();
|
||||
for (name, session) in locked.sessions.iter_mut() {
|
||||
if !session.persistent || session.output_seq == session.last_persisted_seq {
|
||||
if !session.persistent
|
||||
|| restored_screen_is_pending_reattach(session)
|
||||
|| session.output_seq == session.last_persisted_seq
|
||||
{
|
||||
continue;
|
||||
}
|
||||
session.bytes_since_persist = 0;
|
||||
@@ -4411,6 +4418,20 @@ mod tests {
|
||||
let session = locked.sessions.get("work").unwrap();
|
||||
assert!(session.restored_screen.is_some());
|
||||
assert_eq!(attach_snapshot(session, 80, 24), restored);
|
||||
assert_eq!(
|
||||
session.last_persisted_seq, 7,
|
||||
"pre-reattach PTY output must not overwrite the persisted restored screen"
|
||||
);
|
||||
drop(locked);
|
||||
|
||||
flush_persistent_screens(&state);
|
||||
|
||||
let locked = state.lock().unwrap();
|
||||
let session = locked.sessions.get("work").unwrap();
|
||||
assert_eq!(
|
||||
session.last_persisted_seq, 7,
|
||||
"periodic flush must not replace restored screen before client-visible output"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user