HarperFast / HarperFast/harper-pro

Replication W6: Adaptive / dedicated replication threads

Open
#435 0 comments 0 reactions 0 assignees View on GitHub
area:replication enhancement
Dominant language
JavaScript
Stars
3
Forks
0
Avg merge
1d 21h
Merged PRs (30d)
80

Description

**Workstream W6 of #430 · adaptive/dedicated thread management**

## Summary
Replication currently shares HTTP worker event loops, so a bulk copy or an egress-saturated sender steals CPU from request handling *and* conflates event-loop stalls with genuine egress back-pressure (muddying the #218 signal). Recommendation: **dedicated-static replication thread pool first; defer elastic/auto-scaling.**

## Root cause / current state
- Subscriptions are assigned **round-robin across the shared HTTP pool** (`subscriptionManager.ts`); worker selection is hardcoded to `name === 'http'` in several places.
- `replicateOverWS` is reached via `server.ws(...)` — the HTTP server's upgrade handler — so inbound replication rides the same listener/threads as the ops API.
- Per-worker connection caches and `Replicator.load` (cache-miss retrieval) couple replication state to request-serving threads.

## Design direction
1. **A named `'replication'` worker pool** in the threading layer (configurable `replication.threads`).
2. **Route inbound replication WS upgrades to it** (or a second listener bound to the pool).
3. **Decouple cache-miss retrieval connections from streaming connections** (they share `NodeReplicationConnection` today).
4. **Point subscription assignment at the pool.**
5. **Defer elastic** until (a) a runtime named-pool-spawn API exists (none today) and (b) #218's drain/re-route machinery is proven — adaptive *routing* (W5) delivers most of the load relief without adaptive *threading*.
6. **Align with #247** (multi-tenant SNI isolation) so the threading layer grows one general "purpose-pool" capability, not two bespoke ones.

## Scope
- [ ] Named `'replication'` worker pool (static, configurable size)
- [ ] Route inbound replication WS upgrades to the pool
- [ ] Split streaming connections from cache-miss retrieval connections
- [ ] Subscription assignment targets the replication pool
- [ ] (Later) elastic scale-up/down with live `(db,node)` socket drain/migration

## Retires / advances
- High-load isolation of replication from request handling
- [ ] #247 — multi-tenant within process: SNI-based instance routing with isolated workers (adjacent; share the purpose-pool capability)

## Dependencies
**W1** (clean connection registry) and threading-layer named-pool support. Elastic depends additionally on a runtime pool API + proven W5 drain machinery.

## Effort / risk
**L / medium (static pool); XL / high (elastic — later).**

## Acceptance criteria
- A bulk copy or saturated sender no longer steals CPU from request handling.
- The back-pressure signal is not conflated with HTTP-induced event-loop stalls.

---
🤖 Filed by Claude on behalf of Kris.

Contributor guide

Open the contributing guide

Research direction

Start by reading subscriptionManager.ts and the server.ws path that reaches replicateOverWS, then inspect the threading layer, NodeReplicationConnection, and Replicator.load. Separate the static replication-pool work from the deferred elastic work and review dependencies W1, W5, #218, and #247. Done means replication no longer competes with HTTP request handling and back-pressure is no longer confused with HTTP event-loop stalls.

Written by the indexing model from the issue text.

Assessment

Tech stack
nodejs, typescript
Domain
backend, distributed-systems, performance
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.