Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

harness: cap concurrent re-attach streams, so attach readers cannot exhaust Redis connections (follow-up to #471)

Open
#478 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
30/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Active
Tech stack
docker-compose, kubernetes, redis, typescript

Research direction

Start in harness/src/turn-registry.ts, where attach() gives each GET /v1/turn request its own client.duplicate() connection, and follow how that connection is released on stream end, disconnect, and close(). Count open attach readers per process and per session, and return the documented status past the cap. Done means the (N+1)th concurrent attach gets that status and recovers when one ends, reader connections return to zero in a test, and the compose README, vm env example, and k8s base document the new settings. The 429 vs 409 choice and the default cap size are still open.

Written by the indexing model from the issue text.

Description

enhancement

Follow-up from #471 (detachable turns). The final branch review deferred this by ruling.

Goal

One client, or a few, cannot exhaust the harness's Redis connections by opening re-attach streams.

Current state

  • TurnRegistry.attach() (harness/src/turn-registry.ts) gives every GET /v1/turn?sessionId= its own duplicated Redis connection (client.duplicate()). This is necessary because XREAD BLOCK would otherwise stall every other command on the shared client.
  • The connection is released when the stream ends, the client disconnects, or close() runs. Nothing caps how many are open at once. There is no limit per process, per session, or per subject.
  • An authenticated client holding a valid session token can open attach streams in a loop. Each one holds a Redis connection until it ends, so the client can push Redis toward maxclients and starve everything else that shares it: sessions, leases, the control plane.
  • mocactl itself opens one attach per resume, and re-attaches at most 5 times after a dropped stream. Normal use is far below any sensible cap.

Scope

  1. Cap concurrent attach readers per process, for example SH_TURN_ATTACH_MAX with a default sized against the worker's Redis budget. Past the cap, answer 503 {"error":"attach_unavailable"} with Retry-After. mocactl already retries on 503s that carry Retry-After.
  2. Cap concurrent attaches per session at a small number (2–4), so one session cannot use the whole process budget. A further attach for that session gets 429 or 409; pick one and document it.
  3. Optional: serve several attaches of the same turn from one reader in the process (fan-out). That would make the per-session cap mostly moot.
  4. Expose the current attach-reader count in the worker's advisory stats message, so /metrics can show it.

Acceptance

  • With the cap at N, the (N+1)th concurrent attach in a process gets the documented status, and it recovers once one ends.
  • The per-session cap holds across attaches to the same session.
  • A test shows reader connections return to zero after streams end, abort, or close().
  • deploy/compose README, vm env example, and k8s base document the new settings.
Dominant language
TypeScript
Stars
4
Forks
9
Avg merge
9h 2m
Merged PRs (30d)
138

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from rossoctl/moca

All issues in rossoctl/moca

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.