# Socket Daemon

The `core/daemon` package gives every process that opens the same data directory one shared unix socket, and this page explains how `daemon.New` decides whether a process becomes the server or a client.

## Requirements It Satisfies

| # | Requirement | How |
|---|---|---|
| 1 | One shared socket per ToriiDB location | One `Store` is opened by the first process; everyone else talks to it over the socket |
| 2 | Different locations get different sockets | The socket name is a hash of the resolved absolute directory |
| 3 | Repeated `New` on one location shares the socket | `New` dials first; a live socket means client mode |
| 4 | Callers never check their role | `Get`/`Set`/`Del`/... behave the same in both modes |

Transport is a unix socket with a custom length-prefixed JSON frame. There is no HTTP.

## Mode Resolution

`daemon.New(dir, apiKey...)` runs:

1. Reject an empty `dir`.
2. `resolveDir`: `CheckDir(dir, true)` → `filepath.Abs` → `filepath.EvalSymlinks`.
3. `resolveSocket`: `/tmp/toriidb-<uid>-<hex(sha256(realDir)[:8])>.sock`.
4. `probeSocket`: `net.DialTimeout("unix", path, 500ms)`.

| Probe result | Mode | What `New` does |
|---|---|---|
| Dial succeeds | `ModeClient` | Creates a pooled client; no store is opened |
| `ECONNREFUSED` or `ENOENT` | `ModeServer` | Opens `store.New(realDir, apiKey...)` |
| Any other dial error | error | Returns `probe socket <path>: ...` |

| Design rule | Reason |
|---|---|
| Socket directory is hard-coded `/tmp` | `os.TempDir()` reads `$TMPDIR`, which would make the socket depend on environment instead of location |
| Paths go through `EvalSymlinks` | On macOS `/tmp` is a symlink to `/private/tmp`; `relx`, `./relx`, `/tmp/relx/`, `/private/tmp/relx`, and symlinks must converge |
| Liveness is decided by dialing, never by `os.Stat` | `kill -9` leaves the socket file behind; a stale file must not block a new server |
| `uid` is part of the file name | `/tmp` is shared between users |
| `New` takes `dir`, not `*store.Store` | Probing must happen before a store is opened; a client must not open a second store on the same directory |

## Related Pages

- [Lifecycle](/socket-daemon-lifecycle)
- [Data Methods](/socket-daemon-methods)
- [Wire Protocol](/socket-daemon-protocol)
