diff options
author | har7an <99636919+har7an@users.noreply.github.com> | 2023-01-22 18:04:40 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-22 18:04:40 +0000 |
commit | beddfb77a8ef8a5b90db084ad8030d1168f77352 (patch) | |
tree | 1617d19a1b9cbd0be487be1ef06c53ee376f189b /zellij-utils/src | |
parent | b274fc5ab19abe8b3ef7f7afe38897f526263414 (diff) |
Improve client disconnect handling (#2068)
* xtask/run: Use varargs when run with `-data-dir`
Previously any additional arguments passed on the command line were
ignored. Now they are appended to `cargo run ...` as documented.
* server/os_i_o: Improve error message when IPC dies
and display the last send/recv error to the user instead of a generic
"Buffer full" message.
* server/lib: Log error in `send_to_client!`
so we will know when an error occured while trying to send a message to
the client. The most likely cause for this is that the client buffer
filled up and hence we cannot send any new messages. While we still
disconnect the client as before, now we also write a log message that
explains the situation.
* utils/channel: Apply rustfmt
* server/lib: Detect when client responds too slow
and log a message before disconnecting it.
* server/os_i_o: Add retry queue to client senders
that is dynamically allocated on-demand and stores `ServerToClientMsg`
in case the regular IPC channel is currently full. This acts as a
dynamic buffer to hold and buffer messages for a while until the client
hopefully catches up.
Also write a message to the log to indicate when the client is
recognized to be too slow in handling server messages.
* server: apply rustfmt
* utils/ipc: Add session name to "Disconnect" error
* utils/ipc: Fix error message indent
* server/os_i_o: Undo IPC channel extension
via `Vec` and drastically increase the IPC message queue size instead.
Measurements didn't discover a drastic increase in RAM caused by this,
and it is a much easier fix for the problem at hand.
* CHANGELOG: Add PR #2068
Diffstat (limited to 'zellij-utils/src')
-rw-r--r-- | zellij-utils/src/channels.rs | 4 | ||||
-rw-r--r-- | zellij-utils/src/errors.rs | 3 | ||||
-rw-r--r-- | zellij-utils/src/ipc.rs | 26 |
3 files changed, 32 insertions, 1 deletions
diff --git a/zellij-utils/src/channels.rs b/zellij-utils/src/channels.rs index 26a271671..4fdbc8bca 100644 --- a/zellij-utils/src/channels.rs +++ b/zellij-utils/src/channels.rs @@ -4,7 +4,9 @@ use async_std::task_local; use std::cell::RefCell; use crate::errors::{get_current_ctx, ErrorContext}; -pub use crossbeam::channel::{bounded, unbounded, Receiver, RecvError, Select, SendError, Sender}; +pub use crossbeam::channel::{ + bounded, unbounded, Receiver, RecvError, Select, SendError, Sender, TrySendError, +}; /// An [MPSC](mpsc) asynchronous channel with added error context. pub type ChannelWithContext<T> = (Sender<(T, ErrorContext)>, Receiver<(T, ErrorContext)>); diff --git a/zellij-utils/src/errors.rs b/zellij-utils/src/errors.rs index 7fbed99ed..b56bd79a1 100644 --- a/zellij-utils/src/errors.rs +++ b/zellij-utils/src/errors.rs @@ -469,6 +469,9 @@ open an issue on GitHub: #[error("an error occured")] GenericError { source: anyhow::Error }, + + #[error("Client {client_id} is too slow to handle incoming messages")] + ClientTooSlow { client_id: u16 }, } #[cfg(not(target_family = "wasm"))] diff --git a/zellij-utils/src/ipc.rs b/zellij-utils/src/ipc.rs index b264f48e5..81d9e6c89 100644 --- a/zellij-utils/src/ipc.rs +++ b/zellij-utils/src/ipc.rs @@ -117,6 +117,7 @@ pub enum ExitReason { NormalDetached, ForceDetached, CannotAttach, + Disconnect, Error(String), } @@ -133,6 +134,31 @@ impl Display for ExitReason { f, "Session attached to another client. Use --force flag to force connect." ), + Self::Disconnect => { + let session_tip = match crate::envs::get_session_name() { + Ok(name) => format!("`zellij attach {}`", name), + Err(_) => "see `zellij ls` and `zellij attach`".to_string(), + }; + write!( + f, + " +Your zellij client lost connection to the zellij server. + +As a safety measure, you have been disconnected from the current zellij session. +However, the session should still exist and none of your data should be lost. + +This usually means that your terminal didn't process server messages quick +enough. Maybe your system is currently under high load, or your terminal +isn't performant enough. + +There are a few things you can try now: + - Reattach to your previous session and see if it works out better this + time: {session_tip} + - Try using a faster terminal. GPU-accelerated terminals such as Kitty + or Alacritty are cross-platform and known to work well with zellij. + " + ) + }, Self::Error(e) => write!(f, "Error occurred in server:\n{}", e), } } |