mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-12 07:42:32 +00:00
Merge pull request #2586 from PR0M3TH3AN/perf-bound-dm-concurrency-10616621699713195657
perf: bound DM subsystem network concurrency
This commit is contained in:
9 files changed
+134
-31
No files matched your search
@@ -0,0 +1,20 @@
|
||||
# Context - Perf Agent - 2026-02-17
|
||||
|
||||
## Goal
|
||||
Improve application responsiveness by bounding concurrency in background network tasks, specifically for DM signal events and DM service operations.
|
||||
|
||||
## Scope
|
||||
- `js/nostr/dmSignalEvents.js`: Fix unbounded `Promise.all` in `publishDmReadReceipt` and `publishDmTypingIndicator`.
|
||||
- `js/services/dmNostrService.js`: Fix unbounded `Promise.all` in `connect` and `publishSignedEvent`.
|
||||
- `content/docs/guides/upload-content.md`: Fix documentation port number (5500 -> 3000).
|
||||
|
||||
## Assumptions
|
||||
- `pMap` utility works as expected.
|
||||
- `RELAY_BACKGROUND_CONCURRENCY` (3) is an appropriate limit for these operations.
|
||||
|
||||
## Definition of Done
|
||||
- All `Promise.all` usages in targeted functions are replaced with `pMap` with concurrency limits.
|
||||
- `npm run lint` passes.
|
||||
- `npm run test:dm:unit` passes.
|
||||
- `npm run test:dm:integration` passes.
|
||||
- `content/docs/guides/upload-content.md` is updated.
|
||||
@@ -1,27 +1,33 @@
|
||||
# Daily Perf Report - 2026-02-17
|
||||
# Daily Performance Report - 2026-02-17
|
||||
|
||||
**Summary:** Bounded concurrency for channel video fetching; audited upload documentation.
|
||||
**Summary:** Bounded concurrency for DM signal events and DM service initialization to prevent network saturation. Fixed CI failure in `lint:hex` and `unit-tests`.
|
||||
|
||||
## Findings & Fixes
|
||||
|
||||
### P1: Unbounded Concurrency in Channel Profile
|
||||
- **File:** `js/channelProfile.js`
|
||||
- **Function:** `loadUserVideos`
|
||||
- **Issue:** Used `Promise.allSettled` on a map of all relays to fetch videos. This would trigger N concurrent requests (where N = relay count), potentially saturating the network.
|
||||
- **Fix:** Replaced with `pMap` using `RELAY_BACKGROUND_CONCURRENCY` (3). Preserved `Promise.allSettled` semantics by returning `{ status, value|reason }` objects from the mapper.
|
||||
- **Status:** Fixed.
|
||||
### P0: Unbounded Concurrency in DM Subsystem
|
||||
- **Files:** `js/nostr/dmSignalEvents.js`, `js/services/dmNostrService.js`
|
||||
- **Impact:** `Promise.all` was used to map over all relays (potential for 20+ connections simultaneously) for DM read receipts, typing indicators, and service connections.
|
||||
- **Fix:** Replaced with `pMap` using `RELAY_BACKGROUND_CONCURRENCY || 3`.
|
||||
- **Verification:** `npm run test:dm:unit` and `npm run test:dm:integration` passed.
|
||||
|
||||
### P0: Comment Events Concurrency
|
||||
- **File:** `js/nostr/commentEvents.js`
|
||||
- **Status:** Validated as already fixed (uses `pMap`). Updated baseline.
|
||||
### CI Failure (lint:hex)
|
||||
- **Problem:** The `npm run lint:hex` script failed in CI because `git grep` scanned `perf/hits-2026-02-17.txt` (which contained a dump of `webtorrent.min.js` from an agent search) and found hex codes, treating it as a violation.
|
||||
- **Fix:** Updated `scripts/check-hex.js` to exclude agent artifact directories (`perf/`, `test_logs/`, `context/`, `decisions/`, `todo/`).
|
||||
- **Additional Fix:** Increased `maxBuffer` in `scripts/check-hex.js` to 10MB to be robust against large matches.
|
||||
|
||||
## Docs Audit
|
||||
- **Scope:** `content/docs/guides/upload-content.md`
|
||||
- **Verification:**
|
||||
- **CORS Port:** Docs specify `http://localhost:3000`, matching the dev environment.
|
||||
- **Upload Limit:** Docs state 2GB, which matches the client-side hashing limitation.
|
||||
- **Outcome:** Documentation is accurate; no changes needed.
|
||||
### CI Failure (unit-tests)
|
||||
- **Problem:** `tests/unit/services/exploreDataService.test.mjs` failed with `0 !== 1` for "visibility change triggers refresh". The test expected an immediate data refresh when `document.hidden` changed to `false`, but the implementation only started the interval timer.
|
||||
- **Fix:** Updated `handleVisibility` in `js/services/exploreDataService.js` to trigger `refreshWatchHistoryTagCounts` and `refreshTagIdf` immediately when becoming visible.
|
||||
|
||||
### Docs Audit
|
||||
- **Port Alignment:** Verified `content/docs/guides/upload-content.md` correctly specifies port 3000 for CORS, aligning with previous remediation. No changes needed.
|
||||
|
||||
## Metrics
|
||||
- **Login Time:** (No change measured)
|
||||
- **Relay Concurrency:** Enforced limit of 3 for background tasks.
|
||||
- **Login Time:** N/A (change affects background network tasks).
|
||||
- **DM Decrypt Queue:** N/A (network bounding).
|
||||
|
||||
## Decisions
|
||||
- Used `RELAY_BACKGROUND_CONCURRENCY || 3` for DM operations to match relay manager behavior and ensure robustness against missing constants.
|
||||
|
||||
## PRs / Commits
|
||||
- `perf: bound DM subsystem network concurrency & fix CI lint/tests`
|
||||
@@ -0,0 +1,6 @@
|
||||
# Decisions - Perf Agent - 2026-02-17
|
||||
|
||||
- **Decision:** Use `pMap` with `RELAY_BACKGROUND_CONCURRENCY` (3) for DM signal publishing and DM service connection/publishing.
|
||||
- **Rationale:** Prevents network saturation when users have many relays configured. `Promise.all` launches all requests simultaneously, which can cause timeouts or UI lag.
|
||||
- **Decision:** Update documentation port to 3000.
|
||||
- **Rationale:** Matches standard dev environment default.
|
||||
@@ -0,0 +1,30 @@
|
||||
# perf-agent Daily Run - 2026-02-17
|
||||
|
||||
## Status: Completed
|
||||
|
||||
**Goals:**
|
||||
- Identify and fix unbounded concurrency in network operations.
|
||||
- Audit upload documentation.
|
||||
- Fix CI failures (lint and unit tests).
|
||||
|
||||
**Actions:**
|
||||
- **Identified:** Unbounded `Promise.all` usage in `js/nostr/dmSignalEvents.js` and `js/services/dmNostrService.js`.
|
||||
- **Fixed:** Replaced with `pMap` and `RELAY_BACKGROUND_CONCURRENCY || 3`.
|
||||
- **Fixed CI (lint):**
|
||||
- Increased `maxBuffer` in `scripts/check-hex.js` to 10MB.
|
||||
- Added exclusions for agent artifact directories (`perf/`, `test_logs/`, etc.) to `scripts/check-hex.js`.
|
||||
- **Fixed CI (test):** Updated `ExploreDataService.handleVisibility` to trigger immediate data refresh when becoming visible, satisfying `tests/unit/services/exploreDataService.test.mjs`.
|
||||
- **Verified:** Documentation in `content/docs/guides/upload-content.md` correctly specifies port 3000.
|
||||
- **Tested:** Unit and integration tests passed.
|
||||
|
||||
**Files Changed:**
|
||||
- `js/nostr/dmSignalEvents.js`
|
||||
- `js/services/dmNostrService.js`
|
||||
- `js/services/exploreDataService.js`
|
||||
- `scripts/check-hex.js`
|
||||
- `daily-perf-report-2026-02-17.md`
|
||||
- Context/Logs: `context/`, `todo/`, `decisions/`, `test_logs/`
|
||||
|
||||
**Metrics:**
|
||||
- DM network concurrency bounded to 3.
|
||||
- Data refresh reliability on visibility change improved.
|
||||
@@ -10,6 +10,8 @@ import { queueSignEvent } from "./signRequestQueue.js";
|
||||
import { getActiveSigner } from "../nostrClientRegistry.js";
|
||||
import { isSessionActor } from "./sessionActor.js";
|
||||
import { sanitizeRelayList as sanitizeRelayUrls } from "./nip46Client.js";
|
||||
import { pMap } from "../utils/asyncUtils.js";
|
||||
import { RELAY_BACKGROUND_CONCURRENCY } from "./relayConstants.js";
|
||||
|
||||
const DEFAULT_TYPING_EXPIRY_SECONDS = 15;
|
||||
|
||||
@@ -139,8 +141,10 @@ export async function publishDmReadReceipt(
|
||||
client.writeRelays || client.relays,
|
||||
);
|
||||
|
||||
const publishResults = await Promise.all(
|
||||
relayList.map((url) => publishEventToRelay(client.pool, url, signedEvent)),
|
||||
const publishResults = await pMap(
|
||||
relayList,
|
||||
(url) => publishEventToRelay(client.pool, url, signedEvent),
|
||||
{ concurrency: RELAY_BACKGROUND_CONCURRENCY || 3 },
|
||||
);
|
||||
|
||||
const acceptedRelays = publishResults
|
||||
@@ -280,8 +284,10 @@ export async function publishDmTypingIndicator(
|
||||
client.writeRelays || client.relays,
|
||||
);
|
||||
|
||||
const publishResults = await Promise.all(
|
||||
relayList.map((url) => publishEventToRelay(client.pool, url, signedEvent)),
|
||||
const publishResults = await pMap(
|
||||
relayList,
|
||||
(url) => publishEventToRelay(client.pool, url, signedEvent),
|
||||
{ concurrency: RELAY_BACKGROUND_CONCURRENCY || 3 },
|
||||
);
|
||||
|
||||
const acceptedRelays = publishResults
|
||||
|
||||
@@ -8,6 +8,8 @@ import { sanitizeRelayList } from "../nostr/nip46Client.js";
|
||||
import { publishEventToRelay } from "../nostrPublish.js";
|
||||
import logger from "../utils/logger.js";
|
||||
import { SHORT_TIMEOUT_MS } from "../constants.js";
|
||||
import { pMap } from "../utils/asyncUtils.js";
|
||||
import { RELAY_BACKGROUND_CONCURRENCY } from "../nostr/relayConstants.js";
|
||||
|
||||
const DEFAULT_BACKOFF = {
|
||||
baseMs: 1000,
|
||||
@@ -272,10 +274,12 @@ class DmNostrService {
|
||||
|
||||
await this.ensurePool();
|
||||
|
||||
await Promise.all(
|
||||
this.relays.map(async (relayUrl) => {
|
||||
await pMap(
|
||||
this.relays,
|
||||
async (relayUrl) => {
|
||||
await this.connectRelay(relayUrl);
|
||||
}),
|
||||
},
|
||||
{ concurrency: RELAY_BACKGROUND_CONCURRENCY || 3 },
|
||||
);
|
||||
}
|
||||
|
||||
@@ -654,8 +658,9 @@ class DmNostrService {
|
||||
|
||||
await this.ensurePool();
|
||||
|
||||
const results = await Promise.all(
|
||||
relayList.map(async (relayUrl) => {
|
||||
const results = await pMap(
|
||||
relayList,
|
||||
async (relayUrl) => {
|
||||
let result;
|
||||
try {
|
||||
result = await publishEventToRelay(this.pool, relayUrl, signedEvent);
|
||||
@@ -674,7 +679,8 @@ class DmNostrService {
|
||||
}
|
||||
|
||||
return { ...result, relayUrl };
|
||||
}),
|
||||
},
|
||||
{ concurrency: RELAY_BACKGROUND_CONCURRENCY || 3 },
|
||||
);
|
||||
|
||||
return results;
|
||||
|
||||
@@ -36,7 +36,11 @@ const IGNORED_GLOBS = [
|
||||
'bitvid-working-webtorrent/**',
|
||||
'scripts/agent/**',
|
||||
'docs/capacitor-native-app-plan.md',
|
||||
'perf/**'
|
||||
'perf/**',
|
||||
'test_logs/**',
|
||||
'context/**',
|
||||
'decisions/**',
|
||||
'todo/**'
|
||||
];
|
||||
|
||||
const gitArgs = [
|
||||
@@ -56,7 +60,8 @@ for (const glob of IGNORED_GLOBS) {
|
||||
|
||||
// We rely on 'git' being available and 'git grep' supporting -P.
|
||||
// Typically available in most CI/dev environments.
|
||||
const result = spawnSync('git', gitArgs, { encoding: 'utf8' });
|
||||
// Increase maxBuffer to 10MB to prevent ENOBUFS on large minified files
|
||||
const result = spawnSync('git', gitArgs, { encoding: 'utf8', maxBuffer: 10 * 1024 * 1024 });
|
||||
|
||||
if (result.error) {
|
||||
console.error('Failed to execute git grep:', result.error.message);
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# Test Log - Perf Agent - 2026-02-17
|
||||
|
||||
## Pre-fix
|
||||
- [x] Lint check: Passed locally (failed in CI due to `perf/` artifacts).
|
||||
- [x] DM Unit Tests: Passed.
|
||||
- [x] DM Integration Tests: Passed.
|
||||
|
||||
## Post-fix (CI Repair)
|
||||
- [x] Lint check: Passed locally with `perf/` artifacts present (after updating exclusions).
|
||||
- [x] `npm run lint:hex`: Passed.
|
||||
|
||||
## Details
|
||||
- `npm run lint` showed `vendor/webtorrent.min.js` file size warning (expected).
|
||||
- `npm run test:dm:unit` passed 100%.
|
||||
- `npm run test:dm:integration` passed 100%.
|
||||
- CI Failure (lint:hex) was caused by `git grep` matching hex codes in `perf/hits-2026-02-17.txt` (which contained minified code dumps) and `test_logs/`. Added exclusions to `scripts/check-hex.js`.
|
||||
@@ -0,0 +1,8 @@
|
||||
# TODO - Perf Agent - 2026-02-17
|
||||
|
||||
- [ ] Fix `js/nostr/dmSignalEvents.js` @high
|
||||
- [ ] Fix `js/services/dmNostrService.js` @high
|
||||
- [ ] Update `content/docs/guides/upload-content.md` @low
|
||||
- [ ] Run `npm run lint`
|
||||
- [ ] Run `npm run test:dm:unit`
|
||||
- [ ] Run `npm run test:dm:integration`
|
||||
Reference in new issue
Block a user