func combineProfiles(profiles []*profile.Profile, msrcs []plugin.MappingSources) (*profile.Profile, plugin.MappingSources, error) { // Merge profiles. if err := measurement.ScaleProfiles(profiles); err != nil { return nil, nil, err } p, err := profile.Merge(profiles) if err != nil { return nil, nil, err } // Combine mapping sources. msrc := make(plugin.MappingSources) for _, ms := range msrcs { for m, s := range ms { msrc[m] = append(msrc[m], s...) } } return p, msrc, nil }
// concurrentGrab fetches multiple profiles concurrently func concurrentGrab(s *source, fetch plugin.Fetcher, obj plugin.ObjTool, ui plugin.UI) (*profile.Profile, plugin.MappingSources, bool, error) { wg := sync.WaitGroup{} numprofs := len(s.Sources) + len(s.Base) profs := make([]*profile.Profile, numprofs) msrcs := make([]plugin.MappingSources, numprofs) remote := make([]bool, numprofs) errs := make([]error, numprofs) for i, source := range s.Sources { wg.Add(1) go func(i int, src string) { defer wg.Done() profs[i], msrcs[i], remote[i], errs[i] = grabProfile(s, src, 1, fetch, obj, ui) }(i, source) } for i, source := range s.Base { wg.Add(1) go func(i int, src string) { defer wg.Done() profs[i], msrcs[i], remote[i], errs[i] = grabProfile(s, src, -1, fetch, obj, ui) }(i+len(s.Sources), source) } wg.Wait() var save bool var numFailed = 0 for i, src := range s.Sources { if errs[i] != nil { ui.PrintErr(src + ": " + errs[i].Error()) numFailed++ } save = save || remote[i] } for i, src := range s.Base { b := i + len(s.Sources) if errs[b] != nil { ui.PrintErr(src + ": " + errs[b].Error()) numFailed++ } save = save || remote[b] } if numFailed == numprofs { return nil, nil, false, fmt.Errorf("failed to fetch any profiles") } if numFailed > 0 { ui.PrintErr(fmt.Sprintf("fetched %d profiles out of %d", numprofs-numFailed, numprofs)) } scaled := make([]*profile.Profile, 0, numprofs) for _, p := range profs { if p != nil { scaled = append(scaled, p) } } // Merge profiles. if err := measurement.ScaleProfiles(scaled); err != nil { return nil, nil, false, err } p, err := profile.Merge(scaled) if err != nil { return nil, nil, false, err } // Combine mapping sources. msrc := make(plugin.MappingSources) for _, ms := range msrcs { for m, s := range ms { msrc[m] = append(msrc[m], s...) } } return p, msrc, save, nil }