Skip to content

Commit 5ac454b

Browse files
h9jianggopherbot
authored andcommitted
gopls/internal/filewatcher: read and process event in separate goroutine
To work around the potential deadlock in fsnotify, the file watcher had to run dir watching in a separate go routine which make the file watcher complicated and harder to reason about. This CL change the solution by having two methods with clear responsibility but still work around the issue: The run() method is designed to be highly responsive, ensures the fsnotify's events and errors are consumed as soon as possible. A process() method is created to actually handles the time-consuming event processing. Including event conversion, dir watching... As a result, the processor is now processing events in sequence and there is no need for cancelling the ongoing watch attempt. To keep things simple, the input handler function is now separate as event handler and error handler. The event handler is promised to be called sequentially but the error handler maybe called concurrently. For golang/go#74292 Change-Id: I58b06be2022e9a94b4770eb88abff82e94d65ed9 Reviewed-on: https://go-review.googlesource.com/c/tools/+/715882 Auto-Submit: Hongxiang Jiang <hxjiang@golang.org> Reviewed-by: Robert Findley <rfindley@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
1 parent 9d65a90 commit 5ac454b

File tree

3 files changed

+197
-209
lines changed

3 files changed

+197
-209
lines changed

gopls/internal/cmd/mcp.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,10 @@ func (m *headlessMCP) Run(ctx context.Context, args ...string) error {
106106
}
107107
}()
108108

109-
w, err := filewatcher.New(500*time.Millisecond, nil, func(events []protocol.FileEvent, err error) {
110-
if err != nil {
111-
log.Printf("watch error: %v", err)
112-
return
113-
}
114-
109+
errHandler := func(err error) {
110+
log.Printf("watch error: %v", err)
111+
}
112+
w, err := filewatcher.New(500*time.Millisecond, nil, func(events []protocol.FileEvent) {
115113
if len(events) == 0 {
116114
return
117115
}
@@ -127,7 +125,7 @@ func (m *headlessMCP) Run(ctx context.Context, args ...string) error {
127125
case nonempty <- struct{}{}:
128126
default:
129127
}
130-
})
128+
}, errHandler)
131129
if err != nil {
132130
return err
133131
}

0 commit comments

Comments
 (0)