Skip to content

Commit d517112

Browse files
adonovanfindleyr
authored andcommitted
gopls/internal/lsp/protocol: deliver log messages in order
This fixes a predicted bug that was noticed while reading the code. Fixes golang/go#61216 Change-Id: I9614454fbd8538cb0b9eb1f56f11934cb88a7aed Reviewed-on: https://go-review.googlesource.com/c/tools/+/555635 Reviewed-by: Robert Findley <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 9164f2a commit d517112

File tree

1 file changed

+23
-3
lines changed

1 file changed

+23
-3
lines changed

gopls/internal/lsp/protocol/context.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package protocol
77
import (
88
"bytes"
99
"context"
10+
"sync"
1011

1112
"golang.org/x/tools/internal/event"
1213
"golang.org/x/tools/internal/event/core"
@@ -38,8 +39,27 @@ func LogEvent(ctx context.Context, ev core.Event, lm label.Map, mt MessageType)
3839
if event.IsError(ev) {
3940
msg.Type = Error
4041
}
41-
// TODO(adonovan): the goroutine here could cause log
42-
// messages to be delivered out of order! Use a queue.
43-
go client.LogMessage(xcontext.Detach(ctx), msg)
42+
43+
// The background goroutine lives forever once started,
44+
// and ensures log messages are sent in order (#61216).
45+
startLogSenderOnce.Do(func() {
46+
go func() {
47+
for f := range logQueue {
48+
f()
49+
}
50+
}()
51+
})
52+
53+
// Add the log item to a queue, rather than sending a
54+
// window/logMessage request to the client synchronously,
55+
// which would slow down this thread.
56+
ctx2 := xcontext.Detach(ctx)
57+
logQueue <- func() { client.LogMessage(ctx2, msg) }
58+
4459
return ctx
4560
}
61+
62+
var (
63+
startLogSenderOnce sync.Once
64+
logQueue = make(chan func(), 100) // big enough for a large transient burst
65+
)

0 commit comments

Comments
 (0)