feat: auto-discovery
This commit is contained in:
72
index.js
72
index.js
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user