> ## Documentation Index
> Fetch the complete documentation index at: https://docs.monolex.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# SessionActor Pattern

> Lock-free concurrency through single ownership - the heart of Monolex's reliability

# SessionActor Pattern

The SessionActor pattern is the core of Monolex's terminal architecture. It eliminates all locks by ensuring a single owner for all session state.

## The Problem: Lock Contention

Traditional terminal architectures suffer from lock contention:

```
╔═════════════════════════════════════════════════════════════════╗
║  TRADITIONAL ARCHITECTURE (Multiple Owners)                     ║
╠═════════════════════════════════════════════════════════════════╣
║                                                                 ║
║  Thread A (PTY Read)     Thread B (Resize)    Thread C (UI)     ║
║       │                       │                    │            ║
║       ▼                       ▼                    ▼            ║
║  ┌─────────────────────────────────────────────────────────┐    ║
║  │              Mutex<SessionState>                        │    ║
║  │              ↓ Lock contention ↓                        │    ║
║  │              Potential deadlocks                        │    ║
║  └─────────────────────────────────────────────────────────┘    ║
║                                                                 ║
╚═════════════════════════════════════════════════════════════════╝
```

**Problems:**

* Lock contention under high load
* Potential for deadlocks
* Complex reasoning about concurrent access
* Performance degradation

## The Solution: Single Owner

SessionActor owns all state. No locks required.

```
╔═════════════════════════════════════════════════════════════════╗
║  SESSIONACTOR ARCHITECTURE (Single Owner)                       ║
╠═════════════════════════════════════════════════════════════════╣
║                                                                 ║
║  IPC Handler      PTY Socket       Resize Event                 ║
║       │               │                 │                       ║
║       │     MPSC      │      MPSC       │                       ║
║       └───────────────┼─────────────────┘                       ║
║                       ▼                                         ║
║              ┌────────────────────────────────────────────┐     ║
║              │  SessionActor    ← Single owner            │     ║
║              │                                            │     ║
║              │  sessions: HashMap<String, SessionState>   │     ║
║              │  grid_workers: HashMap<String, Sender>     │     ║
║              │  pty_client: PtyClient                     │     ║
║              │                                            │     ║
║              │  NO LOCKS!                                 │     ║
║              └────────────────────────────────────────────┘     ║
║                                                                 ║
╚═════════════════════════════════════════════════════════════════╝
```

## Implementation

### Core Structure

```
╔═════════════════════════════════════════════════════════════════╗
║  SESSIONACTOR STRUCTURE                                         ║
╠═════════════════════════════════════════════════════════════════╣
║                                                                 ║
║  SessionActor owns:                                             ║
║                                                                 ║
║  ┌───────────────────────────────────────────────────────────┐  ║
║  │  SESSION STATE (all sessions)                             │  ║
║  │  ├── Session states (per session)                         │  ║
║  │  ├── Grid workers (per session)                           │  ║
║  │  └── Log workers (per session)                            │  ║
║  └───────────────────────────────────────────────────────────┘  ║
║                                                                 ║
║  ┌───────────────────────────────────────────────────────────┐  ║
║  │  COMMUNICATION                                            │  ║
║  │  ├── Command receiver (MPSC)                              │  ║
║  │  └── Command sender (for external use)                    │  ║
║  └───────────────────────────────────────────────────────────┘  ║
║                                                                 ║
║  ┌───────────────────────────────────────────────────────────┐  ║
║  │  CONNECTIONS                                              │  ║
║  │  ├── PTY Client (daemon communication)                    │  ║
║  │  └── App Handle (Tauri events)                            │  ║
║  └───────────────────────────────────────────────────────────┘  ║
║                                                                 ║
╚═════════════════════════════════════════════════════════════════╝
```

### Command Pattern

All operations are sent as commands through MPSC channels:

```
╔═════════════════════════════════════════════════════════════════╗
║  SESSION COMMANDS                                               ║
╠═════════════════════════════════════════════════════════════════╣
║                                                                 ║
║  Command              Parameters                  Returns       ║
║  ─────────────────    ────────────────────────    ─────────     ║
║  Create               cols, rows                  session_id    ║
║  Write                session_id, data            -             ║
║  Resize               session_id, cols, rows      -             ║
║  Close                session_id                  -             ║
║  Pause                session_id                  -             ║
║  Resume               session_id                  -             ║
║  GridAck              session_id                  -             ║
║                                                                 ║
║  All commands flow through a single MPSC channel                ║
║  → Guaranteed ordering, no race conditions                      ║
║                                                                 ║
╚═════════════════════════════════════════════════════════════════╝
```

### Event Loop

```
╔═════════════════════════════════════════════════════════════════╗
║  SESSIONACTOR EVENT LOOP                                        ║
╠═════════════════════════════════════════════════════════════════╣
║                                                                 ║
║      ┌──────────────────────────────────────────────────────┐   ║
║      │                                                      │   ║
║      │   ┌─────────────────┐                                │   ║
║      │   │ Receive command │ ◀─── MPSC Channel              │   ║
║      │   └────────┬────────┘                                │   ║
║      │            │                                         │   ║
║      │            ▼                                         │   ║
║      │   ┌─────────────────┐                                │   ║
║      │   │ Match command   │                                │   ║
║      │   └────────┬────────┘                                │   ║
║      │            │                                         │   ║
║      │   ┌────────┴────────┬────────┬────────┬─────────┐    │   ║
║      │   ▼                 ▼        ▼        ▼         ▼    │   ║
║      │ Create           Write    Resize   Close    Pause    │   ║
║      │                                                      │   ║
║      │   └─────────────────────────────────────────────┘    │   ║
║      │            │                                         │   ║
║      │            └──────────────────── (loop) ─────────────┘   ║
║      │                                                          ║
║      └──────────────────────────────────────────────────────────┘
║                                                                 ║
║  One command at a time → No locks needed → Simple reasoning     ║
║                                                                 ║
╚═════════════════════════════════════════════════════════════════╝
```

## Benefits

| Aspect          | With Locks | SessionActor |
| --------------- | ---------- | ------------ |
| Deadlocks       | Possible   | Impossible   |
| Lock contention | Under load | None         |
| Reasoning       | Complex    | Simple       |
| Performance     | Degrades   | Consistent   |
| Code complexity | High       | Low          |

## GridWorker: Per-Session Processing

Each session has its own GridWorker running in a separate task:

```
╔═════════════════════════════════════════════════════════════════╗
║  GRIDWORKER PER SESSION                                         ║
╠═════════════════════════════════════════════════════════════════╣
║                                                                 ║
║  SessionActor                                                   ║
║       │                                                         ║
║       ├── GridWorker (session-1) ──▶ emit("pty-grid-session-1") ║
║       │   └── Terminal Parser                                   ║
║       │   └── ACK state                                         ║
║       │                                                         ║
║       ├── GridWorker (session-2) ──▶ emit("pty-grid-session-2") ║
║       │   └── Terminal Parser                                   ║
║       │   └── ACK state                                         ║
║       │                                                         ║
║       └── GridWorker (session-N) ──▶ emit("pty-grid-session-N") ║
║           └── Terminal Parser                                   ║
║           └── ACK state                                         ║
║                                                                 ║
╚═════════════════════════════════════════════════════════════════╝
```

## Message Flow Example

```
User types 'ls' in terminal:

1. Frontend: invoke("write_to_pty", { sessionId, data: "ls\n" })
2. Tauri: Sends SessionCommand::Write to SessionActor
3. SessionActor: Forwards to PtyClient via Unix socket
4. PTY Daemon: Writes to PTY, reads output
5. PTY Daemon: Sends output back via Unix socket
6. SessionActor: Routes to GridWorker
7. GridWorker: Parses terminal data, converts cells
8. GridWorker: emit("pty-grid-{sessionId}", GridUpdate)
9. Frontend: Receives event, injects to xterm buffer
10. Frontend: invoke("grid_ack", { sessionId })
11. Repeat from step 6 if more data pending
```

## Why Not Other Patterns?

### Why not RwLock?

* Still has contention between readers and writers
* Deadlock potential with multiple locks
* Complex upgrade/downgrade semantics

### Why not Actor per Operation?

* Too fine-grained, message passing overhead
* Loses locality of related state
* Harder to reason about ordering

### Why SessionActor?

* Natural boundary: one actor per "thing" (terminal sessions)
* All related state co-located
* Simple event loop, easy to understand
* Guaranteed ordering within actor

## SMPC/OFAC Applied

| Principle | Application                               |
| --------- | ----------------------------------------- |
| **SMPC**  | Single owner = simple reasoning           |
|           | MPSC channels = simple communication      |
|           | No locks = no complexity                  |
| **OFAC**  | Actor pattern emerged from need           |
|           | Per-session workers = natural parallelism |
|           | Commands = organized chaos                |
