compares plc.directory with other mirrors
1
fork

Configure Feed

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

store extra cids

dawn 3490334f 634e7877

+71 -30
+43 -19
index.html
··· 425 425 .miss-status-present { color: #5ab05e; } 426 426 .miss-status-missing { color: #b05a5e; } 427 427 .miss-status-error { color: #555; } 428 + .miss-section-title { 429 + font-size: 0.66rem; 430 + text-transform: uppercase; 431 + letter-spacing: 0.06em; 432 + font-weight: 600; 433 + margin: 0.9rem 0 0.5rem; 434 + padding-bottom: 0.3rem; 435 + border-bottom: 1px solid #1e1e1e; 436 + } 437 + .miss-section-title.missed { color: #7a3022; } 438 + .miss-section-title.extra { color: #7a5a22; } 428 439 429 440 /* ── mobile ── */ 430 441 @media (max-width: 600px) { ··· 1096 1107 missModalData = { mirrorName, snap, url }; 1097 1108 const sm = snap.mirrors[url] ?? {}; 1098 1109 const missed = sm.missedCids ?? {}; 1110 + const extra = sm.extraCids ?? {}; 1099 1111 const dt = new Date(snap.ts); 1100 1112 const timeStr = dt.toLocaleString([], { month: 'short', day: 'numeric', 1101 1113 hour: '2-digit', minute: '2-digit' }); ··· 1103 1115 document.getElementById('missTitle').textContent = `${mirrorName} — missed ops`; 1104 1116 document.getElementById('missTime').textContent = timeStr; 1105 1117 1118 + const mirrorBase = url.replace(/^wss?:\/\//, 'https://').replace(/\/$/, ''); 1106 1119 const body = document.getElementById('missBody'); 1107 - const dids = Object.keys(missed); 1108 - if (!dids.length) { 1109 - body.innerHTML = '<div class="miss-empty">no missed ops recorded for this interval</div>'; 1110 - } else { 1111 - const mirrorBase = url.replace(/^wss?:\/\//, 'https://').replace(/\/$/, ''); 1112 - body.innerHTML = dids.sort().map(did => { 1113 - const cids = missed[did]; 1114 - const cidRows = cids.map(c => 1115 - `<div class="miss-cid-row"><span class="miss-cid" data-cid="${c}">${c}</span><span class="miss-cid-status miss-status-checking">·</span></div>` 1116 - ).join(''); 1117 - return `<div class="miss-did"> 1118 - <div class="miss-did-label">${did} <span style="color:#555;font-size:0.68rem">(${cids.length} op${cids.length !== 1 ? 's' : ''})</span> 1119 - <a class="miss-audit-link" href="https://plc.directory/${did}/log/audit/" target="_blank" rel="noopener">upstream ↗</a> 1120 - <a class="miss-audit-link" href="${mirrorBase}/${did}/log/audit/" target="_blank" rel="noopener">mirror ↗</a> 1121 - </div> 1122 - <div class="miss-cids">${cidRows}</div> 1123 - </div>`; 1124 - }).join(''); 1120 + const missedDids = Object.keys(missed); 1121 + const extraDids = Object.keys(extra); 1122 + 1123 + const renderDidBlock = (did, cids, withStatus) => { 1124 + const cidRows = cids.map(c => 1125 + withStatus 1126 + ? `<div class="miss-cid-row"><span class="miss-cid" data-cid="${c}">${c}</span><span class="miss-cid-status miss-status-checking">·</span></div>` 1127 + : `<div class="miss-cid-row"><span class="miss-cid">${c}</span></div>` 1128 + ).join(''); 1129 + return `<div class="miss-did" data-did="${did}"> 1130 + <div class="miss-did-label">${did} <span style="color:#555;font-size:0.68rem">(${cids.length} op${cids.length !== 1 ? 's' : ''})</span> 1131 + <a class="miss-audit-link" href="https://plc.directory/${did}/log/audit/" target="_blank" rel="noopener">upstream ↗</a> 1132 + <a class="miss-audit-link" href="${mirrorBase}/${did}/log/audit/" target="_blank" rel="noopener">mirror ↗</a> 1133 + </div> 1134 + <div class="miss-cids">${cidRows}</div> 1135 + </div>`; 1136 + }; 1125 1137 1126 - for (const did of dids) checkMirrorAudit(mirrorBase, did, missed[did], gen); 1138 + let html = ''; 1139 + if (missedDids.length) { 1140 + html += `<div class="miss-section-title missed">not seen by mirror (${missedDids.reduce((n, d) => n + missed[d].length, 0)})</div>`; 1141 + html += missedDids.sort().map(did => renderDidBlock(did, missed[did], true)).join(''); 1142 + for (const did of missedDids) checkMirrorAudit(mirrorBase, did, missed[did], gen); 1127 1143 } 1144 + if (extraDids.length) { 1145 + html += `<div class="miss-section-title extra">not seen by upstream (${extraDids.reduce((n, d) => n + extra[d].length, 0)})</div>`; 1146 + html += extraDids.sort().map(did => renderDidBlock(did, extra[did], false)).join(''); 1147 + } 1148 + if (!html) { 1149 + html = '<div class="miss-empty">no missed ops recorded for this interval</div>'; 1150 + } 1151 + body.innerHTML = html; 1128 1152 1129 1153 document.getElementById('missModal').classList.add('show'); 1130 1154 }
+28 -11
server.ts
··· 37 37 missed: number; 38 38 ops: number; // ops received by mirror in this interval 39 39 primaryOps: number; // ops received by primary in this interval 40 - missedCids: Record<string, string[]>; // did -> [cid, ...] 40 + missedCids: Record<string, string[]>; // did -> [cid, ...] primary got, mirror didn't 41 + extraCids: Record<string, string[]>; // did -> [cid, ...] mirror got, primary didn't 41 42 } 42 43 43 44 interface Snapshot { ··· 325 326 // per-mirror accumulators 326 327 const mirrorOps = new Map<string, number>(); 327 328 const mirrorMissed = new Map<string, Record<string, string[]>>(); // url -> did -> [cid] 329 + const mirrorExtra = new Map<string, Record<string, string[]>>(); // url -> did -> [cid] 328 330 for (const [url] of mirrors) { 329 331 if (url === PRIMARY) continue; 330 332 mirrorOps.set(url, 0); 331 333 mirrorMissed.set(url, {}); 334 + mirrorExtra.set(url, {}); 332 335 } 333 336 334 337 for (const [cid, e] of tracker) { 335 - if (e.primaryRecvMs === null || e.primaryRecvMs < cut) continue; 336 - primaryOps++; 337 - for (const [url] of mirrors) { 338 - if (url === PRIMARY) continue; 339 - if (e.mirrorRecv.has(url)) { 340 - mirrorOps.set(url, (mirrorOps.get(url) ?? 0) + 1); 341 - } else { 338 + if (e.primaryRecvMs !== null) { 339 + // op primary received — check which mirrors got it 340 + if (e.primaryRecvMs < cut) continue; 341 + primaryOps++; 342 + for (const [url] of mirrors) { 343 + if (url === PRIMARY) continue; 344 + if (e.mirrorRecv.has(url)) { 345 + mirrorOps.set(url, (mirrorOps.get(url) ?? 0) + 1); 346 + } else { 347 + const did = e.did ?? "?"; 348 + const mm = mirrorMissed.get(url)!; 349 + if (!mm[did]) mm[did] = []; 350 + mm[did].push(cid); 351 + } 352 + } 353 + } else { 354 + // op primary never received — check if any mirror got it this interval 355 + for (const [url, recvMs] of e.mirrorRecv) { 356 + if (url === PRIMARY || recvMs < cut) continue; 357 + const mx = mirrorExtra.get(url); 358 + if (!mx) continue; 342 359 const did = e.did ?? "?"; 343 - const mm = mirrorMissed.get(url)!; 344 - if (!mm[did]) mm[did] = []; 345 - mm[did].push(cid); 360 + if (!mx[did]) mx[did] = []; 361 + mx[did].push(cid); 346 362 } 347 363 } 348 364 } ··· 357 373 ops, 358 374 primaryOps, 359 375 missedCids: mirrorMissed.get(url) ?? {}, 376 + extraCids: mirrorExtra.get(url) ?? {}, 360 377 }; 361 378 } 362 379 return out;