Awesome Reviewers

When adding or modifying concurrency, follow these rules to prevent deadlocks, UI stalls, and racey shutdowns:

1) Keep lock hold-time minimal

2) Isolate blocking work in dedicated workers

3) Make teardown race-safe

4) Never stall critical threads; use offload + timeouts

Illustrative pattern (lock scope + per-session worker):

// Shared map lock only for short lookup/handle cloning.
let writer_tx = {
    let mut sessions = state.sessions.lock().unwrap_or_else(|e| e.into_inner());
    let session = sessions.get_mut(&id).ok_or("missing session")?;
    session.writer_tx.clone() // clone/enqueue handle; do not keep the lock
};

// Fast, non-blocking enqueue; actual blocking happens in the worker.
writer_tx.send(data).map_err(|_| "writer stopped")?;

// Worker thread owns the blocking write.
thread::spawn(move || {
    while let Ok(chunk) = rx.recv() {
        // blocking write_all happens here, not on the caller/UI thread
        let _ = session_writer.write_all(&chunk);
    }
});

Apply these rules whenever you touch: locks protecting shared state, IPC/UI entrypoints, PTY/stdin/stdout plumbing, shutdown/replace logic, or any potentially slow probe.