Enhance command handling: implement monotonic ID for deduplication and improve acknowledgment process
This commit is contained in:
@@ -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 });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user