Enhance command handling: implement monotonic ID for deduplication and improve acknowledgment process

This commit is contained in:
MayaTheShy
2026-03-22 01:29:16 -04:00
parent c47ec63e50
commit a5e6be7f4b

View File

@@ -49,6 +49,7 @@ if (lastUpdate > 0) {
// Pending commands for bridge HTTP polling (fallback)
let pendingCommands = [];
let nextCommandId = 1; // Monotonic ID for deduplication
// ========== Helpers ==========
@@ -70,9 +71,10 @@ function pushCommandToBridge(command) {
}
}
if (!sent) {
// Fallback: queue for HTTP polling
pendingCommands.push({ ...command, timestamp: Date.now() });
console.log(`[Bridge] Queued command via HTTP poll (no WS bridge)`);
// Fallback: queue for HTTP polling with monotonic ID
const id = nextCommandId++;
pendingCommands.push({ ...command, id, timestamp: Date.now() });
console.log(`[Bridge] Queued command #${id} via HTTP poll (no WS bridge)`);
}
}
@@ -413,12 +415,24 @@ app.get('/api/bridge/commands', (req, res) => {
}
});
// Bridge acknowledges commands
// Bridge acknowledges commands by last processed ID
// Only removes commands with id <= lastProcessedId, preventing
// race conditions where new commands arrive between GET and ACK.
app.post('/api/bridge/commands/ack', (req, res) => {
try {
const cleared = pendingCommands.length;
pendingCommands = [];
res.json({ success: true, cleared });
const { lastProcessedId } = req.body || {};
if (lastProcessedId !== undefined && lastProcessedId !== null) {
// Remove only commands that have been processed
const before = pendingCommands.length;
pendingCommands = pendingCommands.filter(cmd => (cmd.id || 0) > lastProcessedId);
const cleared = before - pendingCommands.length;
res.json({ success: true, cleared });
} else {
// Legacy: clear all (backwards-compatible)
const cleared = pendingCommands.length;
pendingCommands = [];
res.json({ success: true, cleared });
}
} catch (error) {
res.status(500).json({ error: error.message });
}