diff --git a/index.js b/index.js index bfc4798..c95d8c2 100644 --- a/index.js +++ b/index.js @@ -73,4 +73,30 @@ loadRoutes(path.join(__dirname, 'routes')); app.listen(port, () => { console.log(`Listening on ${port}`); + // Heartbeat checks + setInterval(() => { + const now = Date.now() / 1000; + global.db.run('SELECT * FROM analytics WHERE heartbeatCheck <= ?', [now], (err, rows) => { + if (err) { + return console.error('Failed to run heartbeat check', err); + } + if (!rows || rows.length === 0) { + return; // No missed heartbeats + } + rows.forEach(row => { + console.log(`Server ${row.id} missed heartbeat check. Marking as inactive.`); + // Set endTime to last known heartbeatCheck time, shutdownReason "missedHeartbeat" + global.db.run( + 'UPDATE analytics SET endTime = ?, shutdownReason = ? WHERE id = ?', + [Math.floor(row.heartbeatCheck), 'missedHeartbeat', row.id], + (err) => { + if (err) { + return console.error(`Failed to mark server ${row.id} as inactive`, err); + } + console.log(`Server ${row.id} marked as inactive due to missed heartbeat.`); + } + ); + }); + }); + }, 1000); }); \ No newline at end of file diff --git a/migrations/001_init.sql b/migrations/001_init.sql index f31dcc4..f30114f 100644 --- a/migrations/001_init.sql +++ b/migrations/001_init.sql @@ -6,5 +6,6 @@ CREATE TABLE IF NOT EXISTS analytics ( serverDuration INTEGER NOT NULL DEFAULT 0, endTime INTEGER DEFAULT NULL, shutdownReason TEXT DEFAULT NULL, - allPlayers BLOB NOT NULL DEFAULT '{}' + allPlayers BLOB NOT NULL DEFAULT '{}', + heartbeatCheck INTEGER NOT NULL ) \ No newline at end of file diff --git a/routes/api/startup.js b/routes/api/startup.js index 1b7ecce..b49973f 100644 --- a/routes/api/startup.js +++ b/routes/api/startup.js @@ -9,9 +9,10 @@ router.post('/', global.auth, async (req, res) => { return res.status(400).json({ error: 'Missing required fields' }); } console.log(`Recording startup: ${serverId} at ${serverStartTime} for place ${placeId} rev ${revision}`); + const firstHeartbeat = Date.now() + ((parseInt(process.env.MAX_HEARTBEAT, 10) || 60) * 1000); db.run( - 'INSERT INTO analytics (id, placeId, revision, startupTime) VALUES (?, ?, ?, ?)', - [serverId, placeId, revision, serverStartTime], + 'INSERT INTO analytics (id, placeId, revision, startupTime, heartbeatCheck) VALUES (?, ?, ?, ?, ?)', + [serverId, placeId, revision, serverStartTime, firstHeartbeat / 1000], function(err) { if (err) { console.error('Failed to record startup data', err);