# Reconnection Design

This document defines the strategy for implementing WebSocket reconnection and command retry logic in `browser-hybrid`.

## Reconnection Requirements

### 1. Trigger Events
A reconnection attempt is triggered by any of the following:
- **WebSocket Close/Error**: `websockets` connection drops or an error event is raised.
- **Send/Recv Timeout**: Command execution exceeds `timeout` without a response (implies socket hang).
- **Health Check Failure**: Periodic `Connection.health_check()` (via `Target.getTargetInfo`) fails.

### 2. State Preservation
During reconnection, the following must be preserved:
- **Active Tab References**: The `tab_id` and metadata must persist.
- **Pending Operations**: Any command in `_pending` that hasn't timed out should be retried after reconnection.
- **Registered Interceptors**: Event listeners (e.g., `Page.loadEventFired`) must be re-registered on the new socket.

### 3. Connection Behavior
- **Queueing**: While a reconnection is in progress, new calls to `_send_cdp()` should be queued (waiting for the `Connection` to become healthy) rather than immediately failing.
- **Retry Logic**: Commands that failed due to a sudden disconnection should be automatically retried once.
- **Configurability**: `max_retries` and `reconnect_delay` must be user-configurable.

---

## State Machine Diagram
```text
  [CONNECTING] ----(Success)---> [HEALTHY] <---(Command Send)
       ^                            |  ^            |
       |                            |  +------------+
    (Retry)                         |
       |                      (Error/Timeout/Close)
       |                            |
       +------- [RECONNECTING] <----+
                     |
                (Max Retries)
                     |
               [FAILED/CLOSED]
```

---

## API Design

### `Connection` Updates
- **`ensure_connected(retry_count=0)`**: New internal method to orchestrate reconnection.
- **`reconnect()`**: Closes existing socket and calls `connect()`.

### `Browser` Updates
- **`reconnect_retries: int = 3`**: Configurable maximum attempts.
- **`reconnect_delay: float = 1.0`**: Delay between attempts (supports exponential backoff).

### New Error Handling
- **`ReconnectionError`**: Raised when `max_retries` is exceeded.
- **`PermanentFailure`**: Raised when Chrome is determined to be unreachable (e.g., `ECONNREFUSED` with no recovery).

---

## Strategy for Retrying Operations
1.  If a `Connection.send()` fails with a network exception or timeout:
2.  Mark the `Connection` as `RECONNECTING`.
3.  Perform the reconnection sequence (disconnect, connect, health-check).
4.  If successful, re-send the original JSON command with its original `id`.
5.  If reconnection fails after `max_retries`, cancel the pending `Future` with the original exception.
