# Thread Safety

## InMemoryStorage

- **Not thread-safe** by default.
- Protect access with external locking when shared between threads.

```python
import threading

from unmake import HistoryManager, InMemoryStorage

manager = HistoryManager(InMemoryStorage())
lock = threading.Lock()

with lock:
    with manager.start_session(script="job.py") as session:
        session.record_operation("fs.move", {"src": "a", "dst": "b"})
```

## SQLiteStorage

- **Thread-safe** for common usage because each operation opens its own SQLite connection.
- SQLite coordinates concurrent access with internal locking.
- Throughput may drop under high contention.
- Prefer one `HistoryManager` per worker thread.

```python
from unmake import HistoryManager, SQLiteStorage


def worker() -> None:
    manager = HistoryManager(SQLiteStorage("shared.db"))
    with manager.start_session(worker="A") as session:
        session.record_operation("noop", {})
```

## Recommended Usage

- Use `SQLiteStorage` in concurrent applications.
- Use `InMemoryStorage` only with explicit locking.
- Avoid sharing unprotected mutable state across threads.
