There is a problem with buffering in control mode. This happens when a pty
produces output faster than a control client can read. The problems are:

- the tmux job grows in memory usage with no upper bound
- even an alert user can't stop an out-of-control job fast enough to avoid
having to wait for many megabytes of output (tmux can read from the pty
very fast, but ssh can be very slow)

To illustrate, I ran "yes" for 3 seconds over ssh and then pressed ^C. It
took 45 seconds to receive the buffered output.

Possible solutions are:
1. Limit the amount of buffering that is done for control clients and force
clients to reload state
2. Cause programs that produce too much output to block
3. Provide clients with a way to force the buffer to be flushed

Taking each in turn:
1. Limit the amount of buffering that is done for control clients and force
clients to reload state
When a control client has too much data in its write buffer, we would stop
sending it new spontaneous messages. For instance, tmux could issue a
%overflow message to indicate this to the client and then refuse to queue
for writing all future %output and other messages. When the client receives
%overflow, it must reinitialize its state (get window layouts and update
them if they've changed, re-download missing history and issue a "control
set-ready" to start up again.

Pros:
- Works automatically with no user interaction
- Doesn't affect non-control clients

Cons:
- Would introduce a very large delay when it triggers--ALL window panes'
partial histories must be refetched
- In pathological cases, downloading history might be worse than receiving
the output
- Buffer too small means this triggers all the time. Buffer too large means
it doesn't trigger enough and the problem of stopping an out-of-control job
remains. If you have lots of moderately talkative window panes, you can't
make the buffer small enough.
- Users would need to constantly tweak & tune the buffer size, but many
wouldn't know about it at all.


2. Cause PTYs that produce too much output to block
This is the traditional way of throttling overly chatty programs, and it
works well because it pushes the pain back to the misbehaving program. A
coarse implementation would stop reading from all ptys when any control
client has too much data in its output buffer, and would resume reading
when they all fall under some low water mark. A better implementation would
keep track of how much output is buffered from each pty and block only
those that are above a high water mark (not sure if this would
be noticeably better though)

Pros:
- Works automatically with no user interaction
- Good user experience for control client users

Cons:
- All clients become as slow as the slowest control client


3. Provide clients with a way to force the buffer to be flushed
When a user sees that there is a program is producing output too quickly,
he could issue a command that flushes the buffers. This is like manually
invoking option #1.

Pros:
- Predictable behavior
- Doesn't affect non-control clients

Cons:
- Would introduce a very large delay when it is triggered--ALL window
panes' partial histories must be refetched
- The tmux process's memory usage can grow without bound if nobody is at
the keyboard
- Requires manual intervention, not obvious to most users

I think #2 is the most sensible solution. It's fairly simple to implement,
works automatically, will usually go unnoticed by the user, and in the
worst case is mitigable by the user detaching the slow client. Thoughts?
------------------------------------------------------------------------------
Better than sec? Nothing is better than sec when it comes to
monitoring Big Data applications. Try Boundary one-second 
resolution app monitoring today. Free.
http://p.sf.net/sfu/Boundary-dev2dev
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to