diff --git a/www/js/version.json b/www/js/version.json index d87fac3..8c4d424 100644 --- a/www/js/version.json +++ b/www/js/version.json @@ -1,5 +1,5 @@ { - "VERSION": "v0.7.79", - "VERSION_NUMBER": "0.7.79", - "BUILD_DATE": "2026-06-30T14:36:42.724Z" + "VERSION": "v0.7.80", + "VERSION_NUMBER": "0.7.80", + "BUILD_DATE": "2026-06-30T14:42:12.863Z" } diff --git a/www/ndk-worker.js b/www/ndk-worker.js index f05291a..a846390 100644 --- a/www/ndk-worker.js +++ b/www/ndk-worker.js @@ -6393,18 +6393,25 @@ async function handlePublish(requestId, event, port) { } catch (_cleanupErr) { /* ignore */ } // --- Failure marking (background, after all batches) --- - const newSkips = Array.from(failedSoFar) + // Skip-mark both explicit rejections AND timeouts. A relay that + // times out is either down, too slow, or unreachable — skip it + // next time to avoid wasting time on it. + const allFailed = [...Array.from(failedSoFar), ...Array.from(timedOutSoFar)]; + const newSkips = allFailed .filter(url => broadcastRelayUrls.has(url) && !skippedRelayUrls.has(url)); if (newSkips.length > 0) { for (const url of newSkips) { + const isTimeout = timedOutSoFar.has(url); skippedRelayUrls.set(url, { - reason: 'publish-rejected', + reason: isTimeout ? 'publish-timeout' : 'publish-rejected', timestamp: Math.floor(Date.now() / 1000), }); } scheduleSkipMarkSave(); - console.log(`[Worker] Skip-marked ${newSkips.length} rejected broadcast relays ` + - `(${timedOutSoFar.size} timeouts excluded)`); + const timeoutCount = newSkips.filter(u => timedOutSoFar.has(u)).length; + const rejectCount = newSkips.length - timeoutCount; + console.log(`[Worker] Skip-marked ${newSkips.length} failed broadcast relays ` + + `(${rejectCount} rejected, ${timeoutCount} timed out)`); } // Return early — we already sent the response above. The rest of @@ -6480,27 +6487,25 @@ async function handlePublish(requestId, event, port) { console.log('[Worker] ❌ Failed relays:', relayResults.failed.length); // --- Failure marking for broadcast relays --------------------------------- - // Persist skip-marks ONLY for broadcast relays that EXPLICITLY rejected - // the publish (auth-required, blocked, invalid, etc.). We do NOT skip-mark - // relays that timed out — with hundreds of relays, a timeout often means - // the relay was slow to connect, not that it's broken. The relay:publish:failed - // listener above separates timeouts (timedOutSoFar) from explicit rejections - // (failedSoFar) by checking the error message for "timeout". + // Skip-mark both explicit rejections AND timeouts. A relay that times + // out is either down, too slow, or unreachable — skip it next time. if (isBroadcast) { - const newSkips = Array.from(failedSoFar) + const allFailed = [...Array.from(failedSoFar), ...Array.from(timedOutSoFar)]; + const newSkips = allFailed .filter(url => broadcastRelayUrls.has(url) && !skippedRelayUrls.has(url)); if (newSkips.length > 0) { for (const url of newSkips) { + const isTimeout = timedOutSoFar.has(url); skippedRelayUrls.set(url, { - reason: 'publish-rejected', + reason: isTimeout ? 'publish-timeout' : 'publish-rejected', timestamp: Math.floor(Date.now() / 1000), }); } scheduleSkipMarkSave(); - console.log(`[Worker] Skip-marked ${newSkips.length} rejected broadcast relays ` + - `(${timedOutSoFar.size} timeouts excluded from skip-marking)`); - } else if (timedOutSoFar.size > 0) { - console.log(`[Worker] ${timedOutSoFar.size} broadcast relays timed out (not skip-marked — will retry next publish)`); + const timeoutCount2 = newSkips.filter(u => timedOutSoFar.has(u)).length; + const rejectCount2 = newSkips.length - timeoutCount2; + console.log(`[Worker] Skip-marked ${newSkips.length} failed broadcast relays ` + + `(${rejectCount2} rejected, ${timeoutCount2} timed out)`); } }