mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 18:31:54 +00:00
add resetable sync.Once for timed caching of ctags globs (#32082)
This commit is contained in:
parent
b098cc60f4
commit
ff87cb8d96
@ -2,14 +2,10 @@ package resolvers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/gobwas/glob"
|
||||
"github.com/opentracing/opentracing-go/log"
|
||||
|
||||
"github.com/sourcegraph/go-ctags"
|
||||
|
||||
gql "github.com/sourcegraph/sourcegraph/cmd/frontend/graphqlbackend"
|
||||
"github.com/sourcegraph/sourcegraph/enterprise/internal/codeintel/policies"
|
||||
store "github.com/sourcegraph/sourcegraph/enterprise/internal/codeintel/stores/dbstore"
|
||||
@ -304,15 +300,10 @@ func (r *resolver) SupportedByCtags(ctx context.Context, filepath string, repoNa
|
||||
return false, "", err
|
||||
}
|
||||
|
||||
for _, allowedLanguage := range ctags.SupportedLanguages {
|
||||
for _, pattern := range mappings[allowedLanguage] {
|
||||
compiled, err := glob.Compile(pattern)
|
||||
if err != nil {
|
||||
return false, "", err
|
||||
}
|
||||
|
||||
if compiled.Match(path.Base(filepath)) {
|
||||
return true, allowedLanguage, nil
|
||||
for language, globs := range mappings {
|
||||
for _, glob := range globs {
|
||||
if glob.Match(filepath) {
|
||||
return true, language, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
34
internal/resetonce/resetable_once.go
Normal file
34
internal/resetonce/resetable_once.go
Normal file
@ -0,0 +1,34 @@
|
||||
package resetonce
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
// Once is a copy of `sync.Once` with a `Reset` method, inspired by
|
||||
// https://github.com/matryer/resync/blob/master/once.go
|
||||
type Once struct {
|
||||
done uint32
|
||||
m sync.Mutex
|
||||
}
|
||||
|
||||
func (o *Once) Do(f func()) {
|
||||
if atomic.LoadUint32(&o.done) == 0 {
|
||||
o.doSlow(f)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Once) doSlow(f func()) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
if o.done == 0 {
|
||||
defer atomic.StoreUint32(&o.done, 1)
|
||||
f()
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Once) Reset() {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
atomic.StoreUint32(&o.done, 0)
|
||||
}
|
||||
@ -8,18 +8,23 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gobwas/glob"
|
||||
"github.com/neelance/parallel"
|
||||
"github.com/opentracing-contrib/go-stdlib/nethttp"
|
||||
"github.com/opentracing/opentracing-go/ext"
|
||||
otlog "github.com/opentracing/opentracing-go/log"
|
||||
|
||||
"github.com/sourcegraph/go-ctags"
|
||||
|
||||
"github.com/sourcegraph/sourcegraph/internal/actor"
|
||||
"github.com/sourcegraph/sourcegraph/internal/api"
|
||||
"github.com/sourcegraph/sourcegraph/internal/authz"
|
||||
"github.com/sourcegraph/sourcegraph/internal/endpoint"
|
||||
"github.com/sourcegraph/sourcegraph/internal/env"
|
||||
"github.com/sourcegraph/sourcegraph/internal/httpcli"
|
||||
"github.com/sourcegraph/sourcegraph/internal/resetonce"
|
||||
"github.com/sourcegraph/sourcegraph/internal/search"
|
||||
"github.com/sourcegraph/sourcegraph/internal/search/result"
|
||||
"github.com/sourcegraph/sourcegraph/internal/trace/ot"
|
||||
@ -61,12 +66,15 @@ type Client struct {
|
||||
// database connection.
|
||||
SubRepoPermsChecker func() authz.SubRepoPermissionChecker
|
||||
|
||||
once sync.Once
|
||||
endpoint *endpoint.Map
|
||||
endpointOnce sync.Once
|
||||
endpoint *endpoint.Map
|
||||
|
||||
langMappingOnce resetonce.Once
|
||||
langMappingCache map[string][]glob.Glob
|
||||
}
|
||||
|
||||
func (c *Client) url(repo api.RepoName) (string, error) {
|
||||
c.once.Do(func() {
|
||||
c.endpointOnce.Do(func() {
|
||||
if len(strings.Fields(c.URL)) == 0 {
|
||||
c.endpoint = endpoint.Empty(errors.New("a symbols service has not been configured"))
|
||||
} else {
|
||||
@ -76,30 +84,48 @@ func (c *Client) url(repo api.RepoName) (string, error) {
|
||||
return c.endpoint.Get(string(repo))
|
||||
}
|
||||
|
||||
func (c *Client) ListLanguageMappings(ctx context.Context, repo api.RepoName) (_ map[string][]string, err error) {
|
||||
mapping := make(map[string][]string)
|
||||
func (c *Client) ListLanguageMappings(ctx context.Context, repo api.RepoName) (_ map[string][]glob.Glob, err error) {
|
||||
c.langMappingOnce.Do(func() {
|
||||
var resp *http.Response
|
||||
resp, err = c.httpPost(ctx, "list-languages", repo, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
resp, err := c.httpPost(ctx, "list-languages", repo, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
// best-effort inclusion of body in error message
|
||||
body, _ := io.ReadAll(io.LimitReader(resp.Body, 200))
|
||||
err = errors.Errorf(
|
||||
"Symbol.ListLanguageMappings http status %d: %s",
|
||||
resp.StatusCode,
|
||||
string(body),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
// best-effort inclusion of body in error message
|
||||
body, _ := io.ReadAll(io.LimitReader(resp.Body, 200))
|
||||
return nil, errors.Errorf(
|
||||
"Symbol.ListLanguageMappings http status %d: %s",
|
||||
resp.StatusCode,
|
||||
string(body),
|
||||
)
|
||||
}
|
||||
mapping := make(map[string][]string)
|
||||
err = json.NewDecoder(resp.Body).Decode(&mapping)
|
||||
|
||||
if err = json.NewDecoder(resp.Body).Decode(&mapping); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
globs := make(map[string][]glob.Glob, len(ctags.SupportedLanguages))
|
||||
|
||||
return mapping, nil
|
||||
for _, allowedLanguage := range ctags.SupportedLanguages {
|
||||
for _, pattern := range mapping[allowedLanguage] {
|
||||
var compiled glob.Glob
|
||||
compiled, err = glob.Compile(pattern)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
globs[allowedLanguage] = append(globs[allowedLanguage], compiled)
|
||||
}
|
||||
}
|
||||
|
||||
c.langMappingCache = globs
|
||||
time.AfterFunc(time.Minute*10, c.langMappingOnce.Reset)
|
||||
})
|
||||
|
||||
return c.langMappingCache, nil
|
||||
}
|
||||
|
||||
// Search performs a symbol search on the symbols service.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user