mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-27 15:17:38 +00:00
fix: Prevent duplicate broadcasts in StreamWatcher
Add deduplication logic to prevent the same line from being broadcast twice when both direct notification and file watcher fire. Uses a simple hash and 50ms time window to detect duplicates. This fixes the double input issue in server-created sessions. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
fbc8954d39
commit
a84e43dadc
1 changed files with 21 additions and 0 deletions
|
|
@ -13,6 +13,8 @@ interface WatcherInfo {
|
||||||
lastOffset: number;
|
lastOffset: number;
|
||||||
lineBuffer: string;
|
lineBuffer: string;
|
||||||
notificationListener?: (update: { sessionId: string; data: string; timestamp: number }) => void;
|
notificationListener?: (update: { sessionId: string; data: string; timestamp: number }) => void;
|
||||||
|
lastBroadcastTime: number;
|
||||||
|
recentBroadcasts: Set<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class StreamWatcher {
|
export class StreamWatcher {
|
||||||
|
|
@ -40,6 +42,8 @@ export class StreamWatcher {
|
||||||
clients: new Set(),
|
clients: new Set(),
|
||||||
lastOffset: 0,
|
lastOffset: 0,
|
||||||
lineBuffer: '',
|
lineBuffer: '',
|
||||||
|
lastBroadcastTime: 0,
|
||||||
|
recentBroadcasts: new Set(),
|
||||||
};
|
};
|
||||||
this.activeWatchers.set(sessionId, watcherInfo);
|
this.activeWatchers.set(sessionId, watcherInfo);
|
||||||
|
|
||||||
|
|
@ -269,6 +273,23 @@ export class StreamWatcher {
|
||||||
* Broadcast a line to all clients
|
* Broadcast a line to all clients
|
||||||
*/
|
*/
|
||||||
private broadcastLine(sessionId: string, line: string, watcherInfo: WatcherInfo): void {
|
private broadcastLine(sessionId: string, line: string, watcherInfo: WatcherInfo): void {
|
||||||
|
// Deduplication: check if we've broadcast this line very recently
|
||||||
|
const now = Date.now();
|
||||||
|
const lineHash = `${line.substring(0, 100)}_${line.length}`; // Simple hash
|
||||||
|
|
||||||
|
if (watcherInfo.recentBroadcasts.has(lineHash) && now - watcherInfo.lastBroadcastTime < 50) {
|
||||||
|
// Skip duplicate within 50ms window
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up old broadcasts
|
||||||
|
if (now - watcherInfo.lastBroadcastTime > 100) {
|
||||||
|
watcherInfo.recentBroadcasts.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
watcherInfo.recentBroadcasts.add(lineHash);
|
||||||
|
watcherInfo.lastBroadcastTime = now;
|
||||||
|
|
||||||
let eventData: string | null = null;
|
let eventData: string | null = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue