private IEnumerable ExecuteCollection(BuiltQuery builtQuery, Stopwatch stopwatch) { var keys = new HashSet <string>(); var fields = builtQuery.Projection?.fields .Select(x => x.Expression) .ToArray(); var skip = builtQuery.Skip ?? 0; var take = builtQuery.Take ?? int.MaxValue; var projection = builtQuery.Projection != null ? ProjectionMapperFactory.GetMapper(builtQuery.Projection) : null; if (projection == null && loggingSettings.NeedLogging(LogLevel.Warning)) { if (warnings.TryAdd(Environment.StackTrace, 0)) { loggingSettings.Log(LogLevel.Warning, $"Query [{builtQuery.Query}] doesn't have .Select(...) construction. It may be critical to the performance because Jira should return all fields of issues."); } } loggingSettings.Log(LogLevel.Debug, $"Query [{builtQuery.Query}] is starting execution"); int got; int maxResults; do { maxResults = Math.Min(take, packetSize); Stopwatch partialStopwatch = null; if (loggingSettings.NeedLogging(LogLevel.Trace)) { partialStopwatch = Stopwatch.StartNew(); loggingSettings.Log(LogLevel.Trace, $"Query's part (startAt: [{skip}], maxResults: [{maxResults}], jql: [{builtQuery.Query}]) is starting execution"); } var request = new JiraIssuesRequest { Jql = builtQuery.Query?.ToString() ?? "", StartAt = skip, MaxResults = maxResults, Fields = fields }; JiraIssuesResponse response; try { response = jira.SelectIssues(request, builtQuery.IssueType); if (partialStopwatch != null) { partialStopwatch.Stop(); loggingSettings.Log(LogLevel.Trace, $"Query's partial execution (startAt: [{skip}], maxResults: [{maxResults}], jql: [{builtQuery.Query}]) is finished. Returned [{response.Issues.Length}] issues, took [{partialStopwatch.Elapsed.TotalMilliseconds}] ms"); } } catch (Exception) { if (partialStopwatch != null) { partialStopwatch.Stop(); loggingSettings.Log(LogLevel.Trace, $"Query's partial execution (startAt: [{skip}], maxResults: [{maxResults}], jql: [{builtQuery.Query}]) is finished. Threw an exception, took [{partialStopwatch.Elapsed.TotalMilliseconds}] ms"); } stopwatch?.Stop(); throw; } got = response.Issues.Length; for (var i = 0; i < response.Issues.Length && take > 0; ++i) { var issue = response.Issues[i]; if (keys.Add(issue.Key)) { yield return(projection != null?projection(issue) : issue); take--; } } skip += packetSize; } while (take > 0 && got == maxResults); if (stopwatch != null) { stopwatch.Stop(); loggingSettings.Log(LogLevel.Trace, $"Query's execution [{builtQuery.Query}] is finished. Returned [{keys.Count}] issues, took [{stopwatch.Elapsed.TotalMilliseconds}] ms"); } }