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

Bound the WebSocket connection manager's internal maps and clean up on abnormal disconnect

Open
#249 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
24/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
nodejs, typescript
Domain
backend

Research direction

Start with src/dashboard/websocket/connection-manager.service.ts (the staleConnections and byUser Maps near lines 148 and 194), then trace the remove paths in connection-pool.service.ts and the raw setTimeout reconnect timers in dashboard-client.service.ts and reconnection.service.ts. Run websocket.stress.spec.ts to see current behaviour. Done means every add has a matching remove on normal, abnormal and timeout closes, reconnect timers are cleared on disconnect, and the stress spec asserts size stabilises.

Written by the indexing model from the issue text.

Description

intermediate performance

Problem

src/dashboard/websocket/connection-manager.service.ts builds Maps keyed by connection and by user — line 148 creates a staleConnections Map and line 194 a byUser Map. src/dashboard/websocket/connection-pool.service.ts:284 builds a similar aggregate.

Reconnection handling in the same area uses raw timers: src/dashboard/websocket/dashboard-client.service.ts:267 and reconnection.service.ts:160 each store a reconnectTimer from setTimeout, and connection-pool.service.ts:203 uses a bare setTimeout.

There is a stress spec at src/dashboard/websocket/websocket.stress.spec.ts (470 lines) and a documented protocol at docs/WEBSOCKET_SPECIFICATION.md, but nothing asserts that these structures shrink when clients disconnect.

Why it matters

WebSocket servers hold their state in the Node process with no external store, so a Map that only ever grows is an unbounded leak. Unlike an HTTP server, there is no per-connection resource release by the runtime — if the disconnect handler misses a path (client crash, network drop, abnormal close), the entry stays for the life of the process.

reconnection.service.ts is 465 lines, and reconnection logic is exactly where stale entries accumulate: a client that disappears but never sends a clean close leaves both its registry entry and its pending reconnect timer.

Suggested Direction

  1. Verify the removal paths. For every add, confirm a matching remove exists for: normal close, abnormal close, error, and heartbeat timeout. Instrument the Maps so a size mismatch is detectable.
  2. Add a heartbeat/ping timeout sweep. The connection health service (src/dashboard/websocket/services/websocket-health.service.ts) is the natural place. Any connection that misses N heartbeats should be forcibly removed and its socket destroyed.
  3. Bound the Maps as a backstop, following the metrics-history.service.ts pattern (configurable max, explicit trim). Treat this as a safety net, not the primary fix — evicting a live connection is a bug, so a size cap that fires during normal operation means a leak upstream.
  4. Clear reconnect timers on disconnect so a dead client does not hold a pending timer for the full backoff.
  5. Extend the stress spec to assert registry size stabilises across many connect/disconnect cycles, including abrupt ones.

Constraints

  • Do not evict a healthy connection; a size cap firing during normal traffic indicates a leak, and the fix belongs upstream.
  • Heartbeat interval and timeout are operational parameters — make them configurable and document the trade-off (shorter detects faster but costs more traffic).
  • Keep docs/WEBSOCKET_SPECIFICATION.md accurate if the heartbeat contract changes.
  • This overlaps with the registry-eviction issue; coordinate so the bounding strategy is consistent rather than duplicated.

Acceptance Criteria

  • Every connection-add path has a matching removal path, verified for normal, abnormal, and timeout closes.
  • Missed-heartbeat connections are detected and cleaned up.
  • Pending reconnect timers are cleared on disconnect.
  • Registry size is exported as a metric.
  • The stress spec asserts size stabilisation across connect/disconnect cycles including abrupt ones.
  • npm test passes with no open handles.
Dominant language
TypeScript
Stars
7
Forks
55
Avg merge
1d 17h
Merged PRs (30d)
5

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 SourceXXL/alian_structure-api

All issues in SourceXXL/alian_structure-api

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.