in shards/shards.go [366:443]
func (ss *shardedSearcher) List(ctx context.Context, r query.Q) (rl *zoekt.RepoList, err error) {
tr := trace.New("shardedSearcher.List", "")
tr.LazyLog(r, true)
metricListRunning.Inc()
defer func() {
metricListRunning.Dec()
if rl != nil {
tr.LazyPrintf("repos size: %d", len(rl.Repos))
tr.LazyPrintf("crashes: %d", rl.Crashes)
}
if err != nil {
tr.LazyPrintf("error: %v", err)
tr.SetError()
}
tr.Finish()
}()
type res struct {
rl *zoekt.RepoList
err error
}
if err := ss.rlock(ctx); err != nil {
return nil, err
}
defer ss.runlock()
tr.LazyPrintf("acquired lock")
shards := ss.getShards()
shardCount := len(shards)
all := make(chan res, shardCount)
tr.LazyPrintf("shardCount: %d", len(shards))
for _, s := range shards {
go func(s zoekt.Searcher) {
metricListShardRunning.Inc()
defer func() {
metricListShardRunning.Dec()
if r := recover(); r != nil {
all <- res{
&zoekt.RepoList{Crashes: 1}, nil,
}
}
}()
ms, err := s.List(ctx, r)
all <- res{ms, err}
}(s.Searcher)
}
crashes := 0
uniq := map[string]*zoekt.RepoListEntry{}
for i := 0; i < shardCount; i++ {
r := <-all
if r.err != nil {
return nil, r.err
}
crashes += r.rl.Crashes
for _, r := range r.rl.Repos {
prev, ok := uniq[r.Repository.Name]
if !ok {
cp := *r
uniq[r.Repository.Name] = &cp
} else {
prev.Stats.Add(&r.Stats)
}
}
}
aggregate := make([]*zoekt.RepoListEntry, 0, len(uniq))
for _, v := range uniq {
aggregate = append(aggregate, v)
}
return &zoekt.RepoList{
Repos: aggregate,
Crashes: crashes,
}, nil
}