aboutsummaryrefslogtreecommitdiffstats
path: root/cmd_windows.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd_windows.go')
-rw-r--r--cmd_windows.go105
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"