Skip to content

decouple PTY sessions from server process for crash survival #103

@almogdepaz

Description

@almogdepaz

Problem

PTY backend sessions are held in-memory inside the wolfpack server process. When the server crashes or restarts (e.g. launchctl kickstart -k, deploy, OOM), all PTY sessions are destroyed — running commands lost, output gone.

This is the main reason tmux backend exists, but tmux adds a dependency and doesn't support /ws/pty binary streaming.

Goal

PTY sessions should survive server restarts, matching tmux's persistence guarantee without requiring tmux.

Approach options

A) External PTY multiplexer process

Spawn a lightweight child process (or daemon) that owns the PTY fds. Server communicates with it over unix socket or fd passing. Server crash → multiplexer keeps running → server reconnects on restart.

Roughly: wolfpack-pty-mux holds the PTYs, wolfpack server is a client.

B) Abduco/dtach-style session detach

Use dtach or similar to wrap each PTY session. Server attaches/detaches on start/stop. Sessions persist independently.

C) Persist to disk + reattach

Write enough state (pid, pty fd path, ring buffer) to disk that a restarted server can reattach to still-running child processes. Fragile — fd inheritance across restarts is tricky.

Considerations

  • Ring buffer contents should also survive (or be reconstructable from scrollback)
  • /ws/pty binary streaming must still work post-reconnect
  • Session list needs to be discoverable on restart (scan for live mux sockets or dtach sessions)
  • Cleanup of truly dead sessions (process exited while server was down)
  • BackendRouter ownership map needs persistence or reconstruction
  • This could eventually obsolete the tmux backend entirely

Current state

  • src/server/pty-backend.ts — sessions map is Map<string, PtySession> in process memory
  • src/server/ring-buffer.ts — 512KB circular buffer per session, also in memory
  • src/server/backend.ts — BackendRouter tracks ownership in Map<string, BackendType>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions