diff options
Diffstat (limited to 'cmd_windows.go')
| -rw-r--r-- | cmd_windows.go | 105 |
1 files changed, 44 insertions, 61 deletions
diff --git a/cmd_windows.go b/cmd_windows.go index 61c7f1d..7df0a9b 100644 --- a/cmd_windows.go +++ b/cmd_windows.go @@ -19,15 +19,15 @@ import ( ) var ( - socketPath = flag.String("socket", "", "Unix socket path to serve events on (required)") - sourceDir = flag.String("dir", "", "Source directory to watch (required)") + sourceDir = flag.String("dir", "", "Source directory to watch (required)") + connect = flag.String("connect", "localhost:5151", "TCP address of the container to connect to") ) func run() { flag.Parse() - if *socketPath == "" || *sourceDir == "" { - fmt.Fprintln(os.Stderr, "Usage: sourcewatch.exe -dir <source> -socket <socket-path>") + if *sourceDir == "" { + fmt.Fprintln(os.Stderr, "Usage: sourcewatch.exe -dir <source> [-connect host:port]") os.Exit(1) } @@ -43,7 +43,7 @@ func run() { stack := NewGitignoreStack(*sourceDir) manifest := scanDirectory(*sourceDir, stack) - logInfo("watcher: found %d files, serving on %s", len(manifest.Files), *socketPath) + logInfo("watcher: found %d files", len(manifest.Files)) watcher, err := fsnotify.NewWatcher() if err != nil { @@ -57,75 +57,61 @@ func run() { os.Exit(1) } - os.Remove(*socketPath) - - ln, err := net.Listen("unix", *socketPath) - if err != nil { - logErrorf("socket: %v", err) - os.Exit(1) - } - defer func() { - ln.Close() - os.Remove(*socketPath) - }() + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) + defer cancel() - var mu sync.Mutex - debounceTimers := make(map[string]*time.Timer) - debounceOps := make(map[string]fsnotify.Op) + for { + if ctx.Err() != nil { + return + } - clients := make(map[net.Conn]bool) - var clientsMu sync.Mutex + logInfo("watcher: connecting to %s ...", *connect) - go func() { + var conn net.Conn for { - conn, err := ln.Accept() - if err != nil { + if ctx.Err() != nil { + return + } + conn, err = net.DialTimeout("tcp", *connect, 5*time.Second) + if err == nil { + break + } + logDebug("connect failed: %v, retrying...", err) + select { + case <-ctx.Done(): return + case <-time.After(2 * time.Second): } - clientsMu.Lock() - clients[conn] = true - clientsMu.Unlock() - logDebug("client connected: %s", conn.RemoteAddr()) + } - go func(c net.Conn) { - sendManifest(c, manifest) + logInfo("watcher: connected, sending manifest ...") - scanner := bufio.NewScanner(c) - for scanner.Scan() { - } + sendManifest(conn, manifest) - clientsMu.Lock() - delete(clients, c) - clientsMu.Unlock() - c.Close() - }(conn) - } - }() + logInfo("watcher: monitoring for changes ...") - broadcast := func(evt FileEvent) { - clientsMu.Lock() - defer clientsMu.Unlock() - for c := range clients { - sendEvent(c, evt) + if !watchLoop(ctx, conn, watcher, manifest, stack) { + conn.Close() + continue } + conn.Close() + return } +} - ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) - defer cancel() - - go func() { - <-ctx.Done() - ln.Close() - }() +func watchLoop(ctx context.Context, conn net.Conn, watcher *fsnotify.Watcher, manifest *Manifest, stack *GitignoreStack) bool { + var mu sync.Mutex + debounceTimers := make(map[string]*time.Timer) + debounceOps := make(map[string]fsnotify.Op) for { select { case <-ctx.Done(): - return + return true case event, ok := <-watcher.Events: if !ok { - return + return true } relPath, err := filepath.Rel(*sourceDir, event.Name) @@ -192,7 +178,6 @@ func run() { return } - // Update manifest srcPath := filepath.Join(*sourceDir, path) switch evt.Op { case "create": @@ -225,15 +210,16 @@ func run() { delete(manifest.Files, path) } - broadcast(evt) + sendEvent(conn, evt) }) mu.Unlock() case err, ok := <-watcher.Errors: if !ok { - return + return true } logErrorf("watcher: %v", err) + return false } } } @@ -307,10 +293,7 @@ func sendManifest(conn net.Conn, manifest *Manifest) { } func sendEvent(conn net.Conn, evt FileEvent) { - msg := &ProtocolMessage{ - Type: "event", - Path: evt.Path, - } + msg := &ProtocolMessage{Path: evt.Path} switch evt.Op { case "create": msg.Type = "event_create" |
