Skip to content

Add marina port: stable, collision-free ports per project/worktree - #16

Merged
danfry1 merged 1 commit into
mainfrom
feat/marina-port
Oct 9, 2026
Merged

danfry1 merged 1 commit into
mainfrom
feat/marina-port

Conversation

@danfry1

@danfry1 danfry1 commented Oct 9, 2026

Copy link
Copy Markdown
Owner

Summary

Parallel coding agents working in parallel git worktrees all default to the same dev port (usually :3000), so the second server fails with EADDRINUSE or silently lands on a random port. marina port gives every project root its own stable port:

pnpm dev --port $(marina port)        # each worktree: its own port, every time
PORT=$(marina port api) cargo run     # several services in one tree
marina port --list                    # all assignments (listening / idle / gone)
marina port --release [name]          # give one back

Design

  • Key: project root of the canonical cwd (each worktree, each monorepo package) + optional service name.
  • Stable: first choice is FNV-1a(key) within the range (default 3100–3999, [ports] range in config); the lease is recorded in $XDG_STATE_HOME/marina/ports.json, so re-runs return the same port.
  • Collision-free: the read-modify-write runs under an exclusive flock and saves via temp-file rename; probing skips ports leased to other keys and ports busy with a foreign listener (netstat + bind probe). A busy port whose listener is a dev target inside this root is the project's own server and is kept; a lease taken over by another process moves (stderr note, "status": "moved" in --json).
  • Self-cleaning: leases for roots that no longer exist (removed worktrees) are dropped on every call.
  • ports::allocate is pure (I/O and busy probe injected); stdout is only the port number so $(marina port) composes.

Docs

README (usage + privacy: ports.json is now a second user-triggered write), DESIGN, CONTEXT glossary, and the agent skill — agents are told to use --port $(marina port) rather than hard-coding ports and to --release when done with a worktree.

Testing

  • cargo fmt --check, clippy -D warnings, cargo test: 127 tests (10 new) — stability across calls and fresh registries, uniqueness across 200 roots × 2 names, foreign takeover → move, deleted-root GC, range exhaustion, release, name validation, range config, CLI usage errors, and 8 threads allocating concurrently through the real locked store (no duplicates, no lost updates).
  • Live on macOS with real git worktrees (isolated XDG_STATE_HOME): repeat calls stable; main / feat-a / feat-b / api all distinct; 10 concurrent marina port processes → 10 unique ports; the project's own server keeps its port; a foreign server taking feat-b's port moves it (3978 → 3979); removing the feat-b worktree drops its lease; --release frees and then reports nothing to release (exit 1).

Parallel agents working in parallel git worktrees all default to the same
dev port. `marina port [name]` returns a port for the current project root
(each worktree and each monorepo package is its own root), the same one on
every call and never shared with another root:

    pnpm dev --port $(marina port)
    PORT=$(marina port api) cargo run

- First choice is FNV-1a(root + name) within the range (default
  3100-3999, configurable via `[ports] range`); assignments are stored in
  `$XDG_STATE_HOME/marina/ports.json`.
- The registry is updated under an exclusive flock and saved via
  temp-file rename, so concurrent callers serialize instead of racing.
- Ports busy with another project's listener are skipped; a lease taken
  over by a foreign process moves (noted on stderr, `moved` in --json),
  while this project's own server keeps its port.
- Leases for deleted roots are dropped on every call; `--release [name]`
  returns one explicitly; `--list` shows all with listening/idle/gone state.
- The allocator (`ports::allocate`) is pure, with I/O and the busy probe
  injected. `logs::state_dir()` is factored out for shared use.

The README privacy section now lists ports.json as a second user-triggered
write; the agent skill tells agents to use `--port $(marina port)` instead
of hard-coding ports.
@danfry1
danfry1 merged commit b20fc17 into main Oct 9, 2026
4 checks passed
@danfry1
danfry1 deleted the feat/marina-port branch October 9, 2026 10:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant