doAttach adds the connection to the map and replays the buffer. It exists separately only for convenience to defer the mutex unlock which is not possible in Attach since it blocks.
(connID string, conn net.Conn)
| 213 | // separately only for convenience to defer the mutex unlock which is not |
| 214 | // possible in Attach since it blocks. |
| 215 | func (rpty *bufferedReconnectingPTY) doAttach(connID string, conn net.Conn) error { |
| 216 | rpty.state.cond.L.Lock() |
| 217 | defer rpty.state.cond.L.Unlock() |
| 218 | |
| 219 | // Write any previously stored data for the TTY. Since the command might be |
| 220 | // short-lived and have already exited, make sure we always at least output |
| 221 | // the buffer before returning, mostly just so tests pass. |
| 222 | prevBuf := slices.Clone(rpty.circularBuffer.Bytes()) |
| 223 | _, err := conn.Write(prevBuf) |
| 224 | if err != nil { |
| 225 | rpty.metrics.WithLabelValues("write").Add(1) |
| 226 | return xerrors.Errorf("write buffer to conn: %w", err) |
| 227 | } |
| 228 | |
| 229 | rpty.activeConns[connID] = conn |
| 230 | |
| 231 | return nil |
| 232 | } |
| 233 | |
| 234 | func (rpty *bufferedReconnectingPTY) Wait() { |
| 235 | _, _ = rpty.state.waitForState(StateClosing) |