# Automatic Reconnection

Browser Hybrid automatically recovers from WebSocket disconnections.

## How It Works

When the WebSocket connection to Chrome drops:

1. Browser Hybrid detects the disconnection
2. Background task attempts to reconnect
3. Operations are queued during reconnection
4. Queued operations execute after connection restores
5. Operations fail if max retries exceeded

## Configuration

```python
from browser_hybrid import Browser

# Default (reconnect enabled)
browser = Browser()

# Disable auto-reconnection
browser = Browser(reconnect=False)

# Customize reconnection
browser = Browser(
    reconnect=True,
    reconnect_max_retries=5,    # Max attempts
    reconnect_backoff=0.5,      # Base backoff in seconds
)

# With callback for status updates
def on_reconnect(message):
    print(f"Reconnection: {message}")

browser = Browser(
    reconnect=True,
    reconnect_callback=on_reconnect
)
```

## Behavior

### During Reconnection

```python
# Operations queue during disconnect
browser.navigate("https://example.com")  # Queued
browser.click("42")                       # Queued

# Operations execute after reconnection
# If reconnection fails, queued operations raise ConnectionError
```

### Connection State

```python
from browser_hybrid.connection import ConnectionState

# Check state
state = browser.state
if state == ConnectionState.CONNECTED:
    print("Ready to go")
elif state == ConnectionState.DISCONNECTED:
    print("Reconnecting...")
elif state == ConnectionState.RECONNECTING:
    print("Attempting to reconnect")
```

### Manual Check

```python
# Check if connected
if browser.is_connected():
    print("Connected to Chrome")
else:
    print("Not connected")
```

## Use Case: Long-Running Automation

```python
from browser_hybrid import Browser

browser = Browser(
    reconnect=True,
    reconnect_max_retries=10,
    reconnect_backoff=1.0,
)

# Long-running task
for url in urls:
    try:
        browser.navigate(url)
        data = browser.get_html()
        process(data)
    except ConnectionError:
        print(f"Lost connection while processing {url}")
        # Browser will attempt to reconnect
```

## Reconnection Backoff

Browser Hybrid uses exponential backoff:

```
Wait time = base_backoff * (2 ^ attempt_number)

Example with base_backoff=0.5:
- Attempt 1: 0.5s
- Attempt 2: 1.0s
- Attempt 3: 2.0s
- Attempt 4: 4.0s
- Attempt 5: 8.0s
```

## Limitations

### Max Retries Exceeded

If reconnection fails after max retries:

```python
try:
    browser.navigate("https://example.com")
except ConnectionError as e:
    print(f"Failed to reconnect: {e}")
    # Handle permanent disconnect
```

### Chrome Closed

If Chrome is closed, reconnection fails:

```python
try:
    browser.navigate("https://example.com")
except ConnectionError:
    print("Chrome is not running")
    # Restart Chrome or exit
```

## Best Practices

1. **Use callbacks for monitoring**

```python
def log_reconnect(msg):
    logger.warning(f"Reconnection: {msg}")

browser = Browser(reconnect_callback=log_reconnect)
```

2. **Set appropriate max_retries**

```python
# Quick fail for short tasks
browser = Browser(reconnect_max_retries=3)

# More patient for long tasks
browser = Browser(reconnect_max_retries=10)
```

3. **Handle ConnectionError**

```python
try:
    # Your automation
    pass
except ConnectionError:
    # Chrome closed or unreachable
    # Implement recovery or alert user
    pass
```

## Implementation Details

The reconnection system uses:

- **Background task**: Monitors connection state
- **Operation queue**: Stores pending operations during disconnect
- **Exponential backoff**: Prevents overwhelming Chrome
- **State machine**: Tracks connection state transitions

```python
# State transitions
CONNECTED → DISCONNECTED → RECONNECTING → CONNECTED
                          ↓
                     (max retries exceeded)
                          ↓
                     DISCONNECTED (permanent)
```