From ed8cac4ac29250ae8c34c82452a5e02425a8e3ba Mon Sep 17 00:00:00 2001 From: Bernhard Guillon Date: Tue, 7 Jul 2026 18:54:02 +0200 Subject: Add sync_done handshake: server signals when ready, client waits before watching --- cmd_linux.go | 4 ++++ cmd_windows.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/cmd_linux.go b/cmd_linux.go index 4239d1d..d9d392e 100644 --- a/cmd_linux.go +++ b/cmd_linux.go @@ -126,6 +126,10 @@ func handleClient(conn net.Conn, stack *GitignoreStack) { logInfo("sync: done") logInfo("watcher: monitoring for changes ...") conn.SetReadDeadline(time.Time{}) // no timeout during event monitoring + doneMsg := &ProtocolMessage{Type: "sync_done"} + doneData, _ := EncodeMessage(doneMsg) + doneData = append(doneData, '\n') + conn.Write(doneData) case "event_create": logDebug("event: create %s", msg.Path) diff --git a/cmd_windows.go b/cmd_windows.go index f728182..f722b47 100644 --- a/cmd_windows.go +++ b/cmd_windows.go @@ -3,6 +3,7 @@ package main import ( + "bufio" "context" "flag" "fmt" @@ -92,6 +93,14 @@ func run() { continue } + logInfo("watcher: waiting for server to finish sync ...") + + if err := waitForSyncDone(conn); err != nil { + logErrorf("wait for sync_done: %v", err) + conn.Close() + continue + } + logInfo("watcher: monitoring for changes ...") // Heartbeat goroutine to detect disconnects @@ -387,6 +396,30 @@ func sendEvent(conn net.Conn, evt FileEvent) error { return err } +func waitForSyncDone(conn net.Conn) error { + scanner := bufio.NewScanner(conn) + scanner.Buffer(make([]byte, 0, 1024*1024), 1024*1024) + conn.SetReadDeadline(time.Now().Add(10 * time.Minute)) // large repos can take a while + defer conn.SetReadDeadline(time.Time{}) + for scanner.Scan() { + msg, err := DecodeMessage(scanner.Bytes()) + if err != nil { + continue + } + switch msg.Type { + case "sync_done": + return nil + case "ping": + // respond to heartbeats during long sync + pong := &ProtocolMessage{Type: "pong"} + data, _ := EncodeMessage(pong) + data = append(data, '\n') + conn.Write(data) + } + } + return fmt.Errorf("connection closed before sync_done") +} + func addWatchersRecursively(watcher *fsnotify.Watcher, root string, stack *GitignoreStack) error { var count, failCount, skippedCount int bufBytes := *bufSizeKB * 1024 -- cgit v1.2.3