From 7de8eddcbe25583eedd478b814c882ab946e0eb2 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Mon, 27 Oct 2025 14:48:29 -0400 Subject: [PATCH] Throttle COUNT diagnostics unless verbose dev mode --- js/nostr/client.js | 31 ++++++++--------- js/nostr/countDiagnostics.js | 65 ++++++++++++++++++++++++++++++++++++ js/nostr/publishHelpers.js | 10 ++---- js/nostr/viewEvents.js | 6 ++-- 4 files changed, 84 insertions(+), 28 deletions(-) create mode 100644 js/nostr/countDiagnostics.js diff --git a/js/nostr/client.js b/js/nostr/client.js index 822de47f..2b5ff8d6 100644 --- a/js/nostr/client.js +++ b/js/nostr/client.js @@ -1,6 +1,6 @@ // js/nostr/client.js -import { isDevMode, isVerboseDevMode } from "../config.js"; +import { isDevMode } from "../config.js"; import { FEATURE_PUBLISH_NIP71 } from "../constants.js"; import { accessControl } from "../accessControl.js"; // 🔧 merged conflicting changes from codex/update-video-publishing-and-parsing-logic vs unstable @@ -58,6 +58,10 @@ import { listVideoComments as listVideoCommentsForClient, subscribeVideoComments as subscribeVideoCommentsForClient, } from "./commentEvents.js"; +import { + logCountTimeoutCleanupFailure, + logRelayCountFailure, +} from "./countDiagnostics.js"; import { publishEventToRelay, publishEventToRelays, @@ -345,9 +349,7 @@ function withRequestTimeout(promise, timeoutMs, onTimeout, message = "Request ti try { onTimeout(); } catch (cleanupError) { - if (isVerboseDevMode) { - devLogger.warn("[nostr] COUNT timeout cleanup failed:", cleanupError); - } + logCountTimeoutCleanupFailure(cleanupError); } } reject(new Error(message)); @@ -5741,20 +5743,15 @@ export class NostrClient { }); const count = this.extractCountValue(frame?.[2]); return { url, ok: true, frame, count }; - } catch (error) { - const isUnsupported = error?.code === "count-unsupported"; - if (isUnsupported) { - this.countUnsupportedRelays.add(url); - } else { - if (isVerboseDevMode) { - devLogger.warn( - `[nostr] COUNT request failed on ${url}:`, - error, - ); - } - } - return { url, ok: false, error, unsupported: isUnsupported }; + } catch (error) { + const isUnsupported = error?.code === "count-unsupported"; + if (isUnsupported) { + this.countUnsupportedRelays.add(url); + } else { + logRelayCountFailure(url, error); } + return { url, ok: false, error, unsupported: isUnsupported }; + } }) ); diff --git a/js/nostr/countDiagnostics.js b/js/nostr/countDiagnostics.js new file mode 100644 index 00000000..c731cf0f --- /dev/null +++ b/js/nostr/countDiagnostics.js @@ -0,0 +1,65 @@ +// js/nostr/countDiagnostics.js +// Centralized helpers for gating high-volume COUNT diagnostics behind +// verbose dev mode and deduplicating repeated warnings so the console stays +// readable during normal development sessions. + +import { devLogger } from "../utils/logger.js"; +import { isVerboseDevMode } from "../config.js"; + +const seenWarningKeys = new Set(); + +function isVerboseCountLoggingEnabled() { + if (typeof window !== "undefined" && window) { + const runtimeFlag = window.__BITVID_VERBOSE_DEV_MODE__; + if (typeof runtimeFlag === "boolean") { + return runtimeFlag; + } + } + return Boolean(isVerboseDevMode); +} + +function logCountWarning(message, args = [], { key, throttle = true } = {}) { + if (!isVerboseCountLoggingEnabled()) { + return; + } + + if (throttle && key) { + const normalizedKey = String(key); + if (seenWarningKeys.has(normalizedKey)) { + return; + } + seenWarningKeys.add(normalizedKey); + } + + devLogger.warn(message, ...args); +} + +export function logCountTimeoutCleanupFailure(error) { + logCountWarning("[nostr] COUNT timeout cleanup failed:", [error], { + key: "count-timeout-cleanup", + }); +} + +export function logRelayCountFailure(url, error) { + const normalizedUrl = + typeof url === "string" && url.trim() ? url.trim() : "(unknown relay)"; + logCountWarning(`[nostr] COUNT request failed on ${normalizedUrl}:`, [error], { + key: `relay:${normalizedUrl}`, + }); +} + +export function logRebroadcastCountFailure(error) { + logCountWarning("[nostr] COUNT request for rebroadcast failed:", [error], { + key: "rebroadcast-count-failure", + }); +} + +export function logViewCountFailure(error) { + logCountWarning("[nostr] COUNT view request failed:", [error], { + key: "view-count-failure", + }); +} + +export function resetCountWarningHistory() { + seenWarningKeys.clear(); +} diff --git a/js/nostr/publishHelpers.js b/js/nostr/publishHelpers.js index 38eea286..79936110 100644 --- a/js/nostr/publishHelpers.js +++ b/js/nostr/publishHelpers.js @@ -1,7 +1,4 @@ -import { - ENSURE_PRESENCE_REBROADCAST_COOLDOWN_SECONDS, - isVerboseDevMode, -} from "../config.js"; +import { ENSURE_PRESENCE_REBROADCAST_COOLDOWN_SECONDS } from "../config.js"; import { publishEventToRelays, assertAnyRelayAccepted, @@ -17,6 +14,7 @@ import { } from "./toolkit.js"; import { DEFAULT_NIP07_PERMISSION_METHODS } from "./nip07Permissions.js"; import { devLogger, userLogger } from "../utils/logger.js"; +import { logRebroadcastCountFailure } from "./countDiagnostics.js"; const REBROADCAST_GUARD_PREFIX = "bitvid:rebroadcast:v1"; const rebroadcastAttemptMemory = new Map(); @@ -1024,9 +1022,7 @@ export async function rebroadcastEvent({ client, eventId, options = {} }) { }) : null; } catch (error) { - if (isVerboseDevMode) { - devLogger.warn("[nostr] COUNT request for rebroadcast failed:", error); - } + logRebroadcastCountFailure(error); } if (countResult?.total && Number(countResult.total) > 0) { diff --git a/js/nostr/viewEvents.js b/js/nostr/viewEvents.js index e0e50563..1d3bf2c0 100644 --- a/js/nostr/viewEvents.js +++ b/js/nostr/viewEvents.js @@ -1,7 +1,6 @@ import { VIEW_COUNT_DEDUPE_WINDOW_SECONDS, VIEW_COUNT_BACKFILL_MAX_DAYS, - isVerboseDevMode, } from "../config.js"; import { VIEW_FILTER_INCLUDE_LEGACY_VIDEO } from "../constants.js"; import { @@ -13,6 +12,7 @@ import { publishEventToRelay } from "../nostrPublish.js"; import { RELAY_URLS } from "./toolkit.js"; import { normalizePointerInput } from "./watchHistory.js"; import { devLogger, userLogger } from "../utils/logger.js"; +import { logViewCountFailure } from "./countDiagnostics.js"; const VIEW_EVENT_GUARD_PREFIX = "bitvid:viewed"; @@ -591,9 +591,7 @@ export async function countVideoViewEvents(client, pointer, options = {}) { } } catch (error) { if (error?.code !== "count-unsupported") { - if (isVerboseDevMode) { - devLogger.warn("[nostr] COUNT view request failed:", error); - } + logViewCountFailure(error); } }