feat: toggle between mesh and star topology

This commit is contained in:
2025-10-25 11:39:56 +02:00
parent 74473cbc26
commit 5850931614
2 changed files with 199 additions and 124 deletions

View File

@@ -584,7 +584,9 @@ class TopologyViewModel extends ViewModel {
isLoading: false,
error: null,
lastUpdateTime: null,
selectedNode: null
selectedNode: null,
topologyMode: 'mesh', // 'mesh' or 'star'
starCenterNode: null // IP of the center node in star mode
});
}
@@ -692,7 +694,7 @@ class TopologyViewModel extends ViewModel {
}
// Build enhanced graph data with actual node connections
// Creates a star topology with the primary node at the center
// Creates either a mesh topology (all nodes connected) or star topology (center node to all others)
async buildEnhancedGraphData(members, primaryNode) {
const nodes = [];
const links = [];
@@ -730,32 +732,53 @@ class TopologyViewModel extends ViewModel {
}
});
// Build links - create a star topology with primary node at center
// Only create links from the primary node to each member
// The cluster data comes from the primary, so it only knows about its direct connections
if (primaryNode) {
logger.debug(`TopologyViewModel: Creating star topology with primary ${primaryNode}`);
nodes.forEach(node => {
// Create a link from primary to each non-primary node
if (node.ip !== primaryNode) {
const member = members.find(m => m.ip === node.ip);
const latency = member?.latency || this.estimateLatency(node, { ip: primaryNode });
logger.debug(`TopologyViewModel: Creating link from ${primaryNode} to ${node.ip} (latency: ${latency}ms)`);
// Build links based on topology mode
const topologyMode = this.get('topologyMode') || 'mesh';
if (topologyMode === 'mesh') {
// Full mesh - connect all nodes to all other nodes
logger.debug('TopologyViewModel: Creating full mesh topology');
for (let i = 0; i < nodes.length; i++) {
for (let j = i + 1; j < nodes.length; j++) {
const sourceNode = nodes[i];
const targetNode = nodes[j];
links.push({
source: primaryNode,
target: node.id,
latency: latency,
sourceNode: nodes.find(n => n.ip === primaryNode),
targetNode: node,
bidirectional: false // Primary -> Member is directional
source: sourceNode.id,
target: targetNode.id,
latency: this.estimateLatency(sourceNode, targetNode),
sourceNode: sourceNode,
targetNode: targetNode,
bidirectional: true
});
}
});
logger.debug(`TopologyViewModel: Created ${links.length} links from primary node`);
} else {
logger.warn('TopologyViewModel: No primary node specified, cannot create links');
}
logger.debug(`TopologyViewModel: Created ${links.length} links in mesh topology`);
} else if (topologyMode === 'star') {
// Star topology - center node connects to all others
const centerNode = this.get('starCenterNode') || primaryNode;
if (centerNode) {
logger.debug(`TopologyViewModel: Creating star topology with center ${centerNode}`);
nodes.forEach(node => {
if (node.ip !== centerNode) {
const member = members.find(m => m.ip === node.ip);
const latency = member?.latency || this.estimateLatency(node, { ip: centerNode });
links.push({
source: centerNode,
target: node.id,
latency: latency,
sourceNode: nodes.find(n => n.ip === centerNode),
targetNode: node,
bidirectional: false
});
}
});
logger.debug(`TopologyViewModel: Created ${links.length} links from center node`);
} else {
logger.warn('TopologyViewModel: No center node specified for star topology');
}
}
return { nodes, links };
@@ -803,6 +826,36 @@ class TopologyViewModel extends ViewModel {
throw error;
}
}
// Toggle topology mode or set star mode with specific center node
async setTopologyMode(mode, centerNodeIp = null) {
logger.debug(`TopologyViewModel: Setting topology mode to ${mode}`, centerNodeIp ? `with center ${centerNodeIp}` : '');
this.setMultiple({
topologyMode: mode,
starCenterNode: centerNodeIp
});
// Rebuild the graph with new topology
await this.updateNetworkTopology();
}
// Toggle between mesh and star modes
async toggleTopologyMode(nodeIp) {
const currentMode = this.get('topologyMode');
const currentCenter = this.get('starCenterNode');
if (currentMode === 'mesh') {
// Switch to star mode with this node as center
await this.setTopologyMode('star', nodeIp);
} else if (currentMode === 'star' && currentCenter === nodeIp) {
// Clicking same center node - switch back to mesh
await this.setTopologyMode('mesh', null);
} else {
// Clicking different node - change star center
await this.setTopologyMode('star', nodeIp);
}
}
}
// Monitoring View Model for cluster resource monitoring