fix limit on neighbours

This commit is contained in:
2026-03-05 21:00:24 +01:00
parent 8bcc6270ca
commit 636cd9a1e4
2 changed files with 22 additions and 14 deletions

View File

@@ -202,17 +202,20 @@ router.get('/', async (req, res, next) => {
if (neighboursResult.status === 'rejected') logger.warn({ asn, error: neighboursResult.reason?.message }, 'Neighbours fetch failed, continuing with partial data'); if (neighboursResult.status === 'rejected') logger.warn({ asn, error: neighboursResult.reason?.message }, 'Neighbours fetch failed, continuing with partial data');
if (prefixesResult.status === 'rejected') logger.warn({ asn, error: prefixesResult.reason?.message }, 'Prefixes fetch failed, continuing with partial data'); if (prefixesResult.status === 'rejected') logger.warn({ asn, error: prefixesResult.reason?.message }, 'Prefixes fetch failed, continuing with partial data');
// Split neighbours // Split neighbours (keep ALL of them, sorted by power)
const upstreams = neighbours.filter(n => n.type === 'left').sort((a, b) => b.power - a.power).slice(0, 10); const allUpstreams = neighbours.filter(n => n.type === 'left').sort((a, b) => b.power - a.power);
const downstreams = neighbours.filter(n => n.type === 'right').sort((a, b) => b.power - a.power).slice(0, 10); const allDownstreams = neighbours.filter(n => n.type === 'right').sort((a, b) => b.power - a.power);
// Resolve names for ALL Level 2 nodes (both upstreams and downstreams) // Resolve names for only the Top 25 of each, to prevent hammering the RIPE API (rate limits)
const level2Asns = [...new Set([...upstreams, ...downstreams].map(n => n.asn))]; const topLevel2Asns = [...new Set([
const level2Names = await resolveNames(level2Asns); ...allUpstreams.slice(0, 25),
...allDownstreams.slice(0, 25)
].map(n => n.asn))];
const level2Names = await resolveNames(topLevel2Asns);
// Level 3: fetch upstreams-of-upstreams for top 5 Level 2 upstreams // Level 3: fetch upstreams-of-upstreams for top 5 Level 2 upstreams
const level3Raw = await Promise.allSettled( const level3Raw = await Promise.allSettled(
upstreams.slice(0, 5).map(async (upstreamNode) => { allUpstreams.slice(0, 5).map(async (upstreamNode) => {
const theirNeighbours = await fetchNeighbours(upstreamNode.asn); const theirNeighbours = await fetchNeighbours(upstreamNode.asn);
const theirUpstreams = theirNeighbours const theirUpstreams = theirNeighbours
.filter(n => n.type === 'left') .filter(n => n.type === 'left')
@@ -234,8 +237,8 @@ router.get('/', async (req, res, next) => {
const graph = { const graph = {
center: { asn, name: overview.name }, center: { asn, name: overview.name },
level2: { level2: {
upstreams: upstreams.map(n => ({ asn: n.asn, name: level2Names[n.asn] || null, power: n.power, v4: n.v4_peers, v6: n.v6_peers })), upstreams: allUpstreams.map(n => ({ asn: n.asn, name: level2Names[n.asn] || null, power: n.power, v4: n.v4_peers, v6: n.v6_peers })),
downstreams: downstreams.map(n => ({ asn: n.asn, name: level2Names[n.asn] || null, power: n.power, v4: n.v4_peers, v6: n.v6_peers })), downstreams: allDownstreams.map(n => ({ asn: n.asn, name: level2Names[n.asn] || null, power: n.power, v4: n.v4_peers, v6: n.v6_peers })),
}, },
level3: level3Data.map(d => ({ level3: level3Data.map(d => ({
parentAsn: d.parentAsn, parentAsn: d.parentAsn,
@@ -254,7 +257,7 @@ router.get('/', async (req, res, next) => {
name: overview.name, name: overview.name,
announced: overview.announced, announced: overview.announced,
type: overview.type, type: overview.type,
prefixes: prefixes.slice(0, 100), prefixes: prefixes, // Export all prefixes without limit
peeringdb, peeringdb,
graph, graph,
}); });

View File

@@ -199,8 +199,13 @@ function renderGraph(graph) {
} }
addNode(graph.center.asn, graph.center.name, 'center'); addNode(graph.center.asn, graph.center.name, 'center');
graph.level2.upstreams.forEach(n => addNode(n.asn, n.name, 'upstream'));
graph.level2.downstreams.forEach(n => addNode(n.asn, n.name, 'downstream')); // Limit graph nodes to top 15 to prevent Physics Engine crash & unreadable hairball
const vizUpstreams = graph.level2.upstreams.slice(0, 15);
const vizDownstreams = graph.level2.downstreams.slice(0, 15);
vizUpstreams.forEach(n => addNode(n.asn, n.name, 'upstream'));
vizDownstreams.forEach(n => addNode(n.asn, n.name, 'downstream'));
graph.level3.forEach(d => { graph.level3.forEach(d => {
d.upstreams.forEach(n => addNode(n.asn, n.name, 'tier1')); d.upstreams.forEach(n => addNode(n.asn, n.name, 'tier1'));
}); });
@@ -210,10 +215,10 @@ function renderGraph(graph) {
const links = []; const links = [];
const centerId = String(graph.center.asn); const centerId = String(graph.center.asn);
graph.level2.upstreams.forEach(n => { vizUpstreams.forEach(n => {
links.push({ source: String(n.asn), target: centerId, type: 'upstream', power: n.power || 1 }); links.push({ source: String(n.asn), target: centerId, type: 'upstream', power: n.power || 1 });
}); });
graph.level2.downstreams.forEach(n => { vizDownstreams.forEach(n => {
links.push({ source: centerId, target: String(n.asn), type: 'downstream', power: n.power || 1 }); links.push({ source: centerId, target: String(n.asn), type: 'downstream', power: n.power || 1 });
}); });
graph.level3.forEach(d => { graph.level3.forEach(d => {