mirror of
https://github.com/golang/go
synced 2024-11-18 16:04:44 -07:00
internal/lsp: limit diagnostics concurrency
Diagnostics runs cannot be canceled until they finish a package. If a user has a very expensive package, we may stack up diagnostics runs to the point where the machine runs out of memory. We see hints of this in various issues. To avoid that, only allow one diagnostics run at a time. We can change the limit later if we want. Updates golang/go#37223. Change-Id: Icd0eec4da936153306cf0a1f7175ae2b4b265272 Reviewed-on: https://go-review.googlesource.com/c/tools/+/219958 Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
parent
66de428735
commit
33153249e7
@ -44,6 +44,14 @@ func (s *Server) diagnose(ctx context.Context, snapshot source.Snapshot, alwaysA
|
||||
ctx, done := trace.StartSpan(ctx, "lsp:background-worker")
|
||||
defer done()
|
||||
|
||||
// Wait for a free diagnostics slot.
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
case s.diagnosticsSema <- struct{}{}:
|
||||
}
|
||||
defer func() { <-s.diagnosticsSema }()
|
||||
|
||||
allReports := make(map[diagnosticKey][]source.Diagnostic)
|
||||
var reportsMu sync.Mutex
|
||||
var wg sync.WaitGroup
|
||||
|
@ -85,10 +85,7 @@ func testLSP(t *testing.T, exporter packagestest.Exporter) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r := &runner{
|
||||
server: &Server{
|
||||
session: session,
|
||||
delivered: map[span.URI]sentDiagnostics{},
|
||||
},
|
||||
server: NewServer(session, nil),
|
||||
data: datum,
|
||||
ctx: ctx,
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ import (
|
||||
"golang.org/x/tools/internal/span"
|
||||
)
|
||||
|
||||
const concurrentAnalyses = 1
|
||||
|
||||
// NewServer creates an LSP server and binds it to handle incoming client
|
||||
// messages on on the supplied stream.
|
||||
func NewServer(session source.Session, client protocol.Client) *Server {
|
||||
@ -23,6 +25,7 @@ func NewServer(session source.Session, client protocol.Client) *Server {
|
||||
delivered: make(map[span.URI]sentDiagnostics),
|
||||
session: session,
|
||||
client: client,
|
||||
diagnosticsSema: make(chan struct{}, concurrentAnalyses),
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,6 +57,9 @@ type Server struct {
|
||||
// delivered is a cache of the diagnostics that the server has sent.
|
||||
deliveredMu sync.Mutex
|
||||
delivered map[span.URI]sentDiagnostics
|
||||
|
||||
// diagnosticsSema limits the concurrency of diagnostics runs, which can be expensive.
|
||||
diagnosticsSema chan struct{}
|
||||
}
|
||||
|
||||
// sentDiagnostics is used to cache diagnostics that have been sent for a given file.
|
||||
|
Loading…
Reference in New Issue
Block a user