private async Task <bool> TriageHelixLogsAsync(ModelBuildAttempt modelBuildAttempt, ModelTrackingIssue modelTrackingIssue) { Debug.Assert(modelBuildAttempt.ModelBuild is object); Debug.Assert(modelTrackingIssue.IsActive); Debug.Assert(modelTrackingIssue.SearchQuery is object); var request = new SearchHelixLogsRequest() { Limit = 100, }; request.ParseQueryString(modelTrackingIssue.SearchQuery); var query = request.Filter(Context.ModelTestResults) .Where(x => x.ModelBuild.Id == modelBuildAttempt.ModelBuild.Id && x.ModelTestRun.Attempt == modelBuildAttempt.Attempt); // TODO: selecting a lot of info here. Can improve perf by selecting only the needed // columns. The search helix logs page already optimizes this. Consider factoring out // the shared code. var testResultList = await query.ToListAsync().ConfigureAwait(false); var buildInfo = modelBuildAttempt.ModelBuild.GetBuildInfo(); var helixLogInfos = testResultList .Select(x => x.GetHelixLogInfo()) .SelectNotNull() .Select(x => (buildInfo, x)); var results = await HelixServer.SearchHelixLogsAsync( helixLogInfos, request, onError : x => Logger.LogWarning(x.Message)).ConfigureAwait(false); var any = false; foreach (var result in results) { any = true; var modelMatch = new ModelTrackingIssueMatch() { ModelBuildAttempt = modelBuildAttempt, ModelTrackingIssue = modelTrackingIssue, HelixLogKind = result.HelixLogKind, HelixLogUri = result.HelixLogUri, }; Context.ModelTrackingIssueMatches.Add(modelMatch); } return(any); }