feat(cluster): add GET /:id/ping to probe node agent reachability and latency
This commit is contained in:
parent
3128ab43b3
commit
4dd377e28d
1 changed files with 27 additions and 1 deletions
|
|
@ -66,6 +66,32 @@ router.post('/heartbeat', async (req, res, next) => {
|
|||
} catch (err) { next(err); }
|
||||
});
|
||||
|
||||
// GET /:id/ping – probe the node's api_url/health endpoint directly
|
||||
router.get('/:id/ping', async (req, res, next) => {
|
||||
try {
|
||||
const r = await pool.query(
|
||||
'SELECT id, hostname, api_url FROM cluster_nodes WHERE id = $1',
|
||||
[req.params.id]
|
||||
);
|
||||
if (r.rowCount === 0) return res.status(404).json({ error: 'Node not found' });
|
||||
|
||||
const node = r.rows[0];
|
||||
if (!node.api_url) return res.json({ reachable: false, reason: 'no api_url registered' });
|
||||
|
||||
const start = Date.now();
|
||||
try {
|
||||
const upstream = await fetch(`${node.api_url}/health`, {
|
||||
signal: AbortSignal.timeout(4000),
|
||||
});
|
||||
const latency_ms = Date.now() - start;
|
||||
const body = await upstream.json().catch(() => ({}));
|
||||
res.json({ reachable: upstream.ok, latency_ms, status: upstream.status, agent: body });
|
||||
} catch (err) {
|
||||
res.json({ reachable: false, latency_ms: Date.now() - start, reason: err.message });
|
||||
}
|
||||
} catch (err) { next(err); }
|
||||
});
|
||||
|
||||
// DELETE /:id – deregister a node
|
||||
router.delete('/:id', async (req, res, next) => {
|
||||
try {
|
||||
|
|
@ -73,7 +99,7 @@ router.delete('/:id', async (req, res, next) => {
|
|||
'DELETE FROM cluster_nodes WHERE id = $1 RETURNING id',
|
||||
[req.params.id]
|
||||
);
|
||||
if (r.rowCount === 0) return res.status(404).json({ error: 'Node not found' });
|
||||
if (r.rowCount === 0) return res.status(404).json({ error: 'Node not found' });;
|
||||
res.json({ ok: true });
|
||||
} catch (err) { next(err); }
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue