compares plc.directory with other mirrors
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

calculate coverage and ops across all snapshots we have

dawn 9305c5a2 3490334f

+23 -30
+10 -20
index.html
··· 443 443 444 444 .section-head { flex-wrap: wrap; gap: 0.35rem 0.6rem; } 445 445 446 - /* hide total-events (col 2) and bar (col 7) on small screens */ 447 - thead tr th:nth-child(2), 448 - tbody tr td:nth-child(2), 449 - thead tr th:nth-child(7), 450 - tbody tr td:nth-child(7) { display: none; } 446 + /* hide bar (col 6) on small screens */ 447 + thead tr th:nth-child(6), 448 + tbody tr td:nth-child(6) { display: none; } 451 449 452 450 /* let lag column break more gracefully */ 453 - tbody tr td:nth-child(6) { font-size: 0.72rem; line-height: 1.4; } 451 + tbody tr td:nth-child(5) { font-size: 0.72rem; line-height: 1.4; } 454 452 455 453 .hist-label { width: 76px; font-size: 0.67rem; } 456 454 ··· 481 479 <div class="section-head"> 482 480 <h2>Coverage</h2> 483 481 <span class="meta"> 484 - 15 min window &nbsp;·&nbsp; lag = mirror recv − primary recv, same server clock 482 + aggregated over all snapshots &nbsp;·&nbsp; lag = mirror recv − primary recv, same server clock 485 483 &nbsp;·&nbsp; <b id="lastUpdated">–</b> 486 484 </span> 487 485 </div> ··· 497 495 </span> 498 496 </th> 499 497 <th class="th-r"> 500 - <span class="tip-label">total ops</span> 501 - <span class="tip"> 502 - <span class="tip-title">total ops</span> 503 - All operations received from this host since the server started, across all op types. 504 - Not windowed — resets on server restart. 505 - </span> 506 - </th> 507 - <th class="th-r"> 508 498 <span class="tip-label">ops</span> 509 499 <span class="tip"> 510 500 <span class="tip-title">ops</span> 511 - Operations received from this host in the rolling <em>15-minute window</em>. 501 + Operations received from this host, summed across all stored snapshots. 512 502 Used as the numerator for coverage and missed calculations. 513 503 </span> 514 504 </th> ··· 547 537 </tr> 548 538 </thead> 549 539 <tbody id="covBody"> 550 - <tr class="empty-row"><td colspan="7">connecting to server…</td></tr> 540 + <tr class="empty-row"><td colspan="6">connecting to server…</td></tr> 551 541 </tbody> 552 542 </table> 553 543 ··· 693 683 renderHistory(stats, snaps); 694 684 } catch { 695 685 document.getElementById('covBody').innerHTML = 696 - '<tr class="empty-row"><td colspan="7">server unavailable</td></tr>'; 686 + '<tr class="empty-row"><td colspan="6">server unavailable</td></tr>'; 697 687 document.getElementById('lastUpdated').textContent = 'offline'; 698 688 } 699 689 } ··· 717 707 const entries = Object.values(stats); 718 708 if (!entries.length) { 719 709 document.getElementById('covBody').innerHTML = 720 - '<tr class="empty-row"><td colspan="7">no mirrors tracked</td></tr>'; 710 + '<tr class="empty-row"><td colspan="6">no mirrors tracked</td></tr>'; 721 711 return; 722 712 } 723 713 ··· 753 743 <span class="td-name">${m.name}</span> 754 744 </span> 755 745 </td> 756 - <td>${m.totalEvents.toLocaleString()}</td> 746 + 757 747 <td>${m.opsInWindow.toLocaleString()}</td> 758 748 <td>${covStr}</td> 759 749 <td>${missStr}</td>
+13 -10
server.ts
··· 267 267 return sorted[Math.max(0, i)]; 268 268 } 269 269 270 - // Rolling window stats for the live coverage table. 270 + // Coverage stats aggregated from all stored snapshots. 271 271 function computeStats(): Record<string, unknown> { 272 - const cut = Date.now() - WINDOW_MS; 273 272 let primaryOps = 0; 274 - const mirrorOps = new Map<string, number>(); 273 + const mirrorOps = new Map<string, number>(); 274 + const mirrorMissed = new Map<string, number>(); 275 275 276 - for (const [, e] of tracker) { 277 - if (e.primaryRecvMs === null || e.primaryRecvMs < cut) continue; 278 - primaryOps++; 279 - for (const [mu] of e.mirrorRecv) { 280 - mirrorOps.set(mu, (mirrorOps.get(mu) ?? 0) + 1); 276 + for (const snap of snapshots) { 277 + const entries = Object.entries(snap.mirrors); 278 + if (!entries.length) continue; 279 + // primaryOps is the same across all mirror entries in a snapshot 280 + primaryOps += entries[0][1].primaryOps; 281 + for (const [url, sm] of entries) { 282 + mirrorOps.set(url, (mirrorOps.get(url) ?? 0) + sm.ops); 283 + mirrorMissed.set(url, (mirrorMissed.get(url) ?? 0) + sm.missed); 281 284 } 282 285 } 283 286 ··· 285 288 for (const [url, m] of mirrors) { 286 289 const isPrimary = url === PRIMARY; 287 290 const opsInWindow = isPrimary ? primaryOps : (mirrorOps.get(url) ?? 0); 288 - const missed = isPrimary ? 0 : Math.max(0, primaryOps - opsInWindow); 291 + const missed = isPrimary ? 0 : (mirrorMissed.get(url) ?? 0); 289 292 const coverage = (!isPrimary && primaryOps > 0) ? opsInWindow / primaryOps : null; 290 293 const rtt = meanRtt(m); 291 294 ··· 307 310 out[url] = { 308 311 name: m.name, url, isPrimary, 309 312 connected: m.connected, 310 - totalEvents: m.totalEvents, 313 + totalEvents: opsInWindow, 311 314 opsInWindow, primaryOps, missed, coverage, 312 315 lagStats, 313 316 rttMs: rtt != null ? Math.round(rtt) : null,