feat: auto-discovery

This commit is contained in:
2025-08-25 12:05:51 +02:00
parent f72e4ba220
commit 5977a37d6c
8 changed files with 552 additions and 3 deletions

View File

@@ -7,6 +7,10 @@ const SporeApiClient = require('./src/client');
const app = express();
const PORT = process.env.PORT || 3001;
// Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// UDP discovery configuration
const UDP_PORT = 4210;
const DISCOVERY_MESSAGE = 'CLUSTER_DISCOVERY';
@@ -149,6 +153,31 @@ function selectBestPrimaryNode() {
return bestNode;
}
// Function to randomly select a primary node
function selectRandomPrimaryNode() {
if (discoveredNodes.size === 0) {
return null;
}
// Convert discovered nodes to array and filter out current primary
const availableNodes = Array.from(discoveredNodes.keys()).filter(ip => ip !== primaryNodeIp);
if (availableNodes.length === 0) {
// If no other nodes available, keep current primary
return primaryNodeIp;
}
// Randomly select from available nodes
const randomIndex = Math.floor(Math.random() * availableNodes.length);
const randomNode = availableNodes[randomIndex];
// Update primary node
primaryNodeIp = randomNode;
console.log(`Randomly selected new primary node: ${randomNode}`);
return randomNode;
}
// Initialize client when a node is discovered
function updateSporeClient() {
const nodeIp = selectBestPrimaryNode();
@@ -221,6 +250,49 @@ app.post('/api/discovery/refresh', (req, res) => {
}
});
// API endpoint to randomly select a new primary node
app.post('/api/discovery/random-primary', (req, res) => {
try {
if (discoveredNodes.size === 0) {
return res.status(404).json({
error: 'No nodes available',
message: 'No SPORE nodes have been discovered yet'
});
}
// Randomly select a new primary node
const randomNode = selectRandomPrimaryNode();
if (!randomNode) {
return res.status(500).json({
error: 'Selection failed',
message: 'Failed to select a random primary node'
});
}
// Update the client with the new primary node
updateSporeClient();
// Get current timestamp for the response
const timestamp = req.body && req.body.timestamp ? req.body.timestamp : new Date().toISOString();
res.json({
success: true,
message: `Randomly selected new primary node: ${randomNode}`,
primaryNode: primaryNodeIp,
totalNodes: discoveredNodes.size,
clientInitialized: !!sporeClient,
timestamp: timestamp
});
} catch (error) {
console.error('Error selecting random primary node:', error);
res.status(500).json({
error: 'Random selection failed',
message: error.message
});
}
});
// API endpoint to manually set primary node
app.post('/api/discovery/primary/:ip', (req, res) => {
try {