diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-28 09:09:49 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-28 09:09:49 +0300 |
commit | c7836133e0d9287e147e9e19099e058a37e87a9a (patch) | |
tree | ca6c83f774635930f10bb4ee1a655c7c255eabe3 /lib/gitlab/analytics | |
parent | 61ae9de492194653156cdd6e2b528e1dec5c99b6 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/gitlab/analytics')
9 files changed, 82 insertions, 30 deletions
diff --git a/lib/gitlab/analytics/cycle_analytics/average.rb b/lib/gitlab/analytics/cycle_analytics/average.rb index a449b71b165..7140d31d536 100644 --- a/lib/gitlab/analytics/cycle_analytics/average.rb +++ b/lib/gitlab/analytics/cycle_analytics/average.rb @@ -7,9 +7,10 @@ module Gitlab include Gitlab::Utils::StrongMemoize include StageQueryHelpers - def initialize(stage:, query:) + def initialize(stage:, query:, params: {}) @stage = stage @query = query + @params = params end def seconds @@ -22,7 +23,7 @@ module Gitlab private - attr_reader :stage + attr_reader :stage, :params # rubocop: disable CodeReuse/ActiveRecord def select_average diff --git a/lib/gitlab/analytics/cycle_analytics/base_query_builder.rb b/lib/gitlab/analytics/cycle_analytics/base_query_builder.rb index 4dec71b35e8..2c39b78c2d9 100644 --- a/lib/gitlab/analytics/cycle_analytics/base_query_builder.rb +++ b/lib/gitlab/analytics/cycle_analytics/base_query_builder.rb @@ -5,6 +5,7 @@ module Gitlab module CycleAnalytics class BaseQueryBuilder include Gitlab::CycleAnalytics::MetricsTables + include StageQueryHelpers delegate :subject_class, to: :stage @@ -13,6 +14,8 @@ module Gitlab Issue.to_s => IssuesFinder }.freeze + DEFAULT_END_EVENT_FILTER = :finished + def initialize(stage:, params: {}) @stage = stage @params = build_finder_params(params) @@ -22,8 +25,7 @@ module Gitlab def build query = finder.execute query = stage.start_event.apply_query_customization(query) - query = stage.end_event.apply_query_customization(query) - query.where(duration_condition) + apply_end_event_query_customization(query) end # rubocop: enable CodeReuse/ActiveRecord @@ -46,6 +48,7 @@ module Gitlab def build_finder_params(params) {}.tap do |finder_params| finder_params[:current_user] = params[:current_user] + finder_params[:end_event_filter] = params[:end_event_filter] || DEFAULT_END_EVENT_FILTER add_parent_model_params!(finder_params) add_time_range_params!(finder_params, params[:from], params[:to]) @@ -62,6 +65,17 @@ module Gitlab finder_params[:created_after] = from || 30.days.ago finder_params[:created_before] = to if to end + + # rubocop: disable CodeReuse/ActiveRecord + def apply_end_event_query_customization(query) + if in_progress? + stage.end_event.apply_negated_query_customization(query) + else + query = stage.end_event.apply_query_customization(query) + query.where(duration_condition) + end + end + # rubocop: enable CodeReuse/ActiveRecord end end end diff --git a/lib/gitlab/analytics/cycle_analytics/data_collector.rb b/lib/gitlab/analytics/cycle_analytics/data_collector.rb index 20208816766..7d0ad4e19f6 100644 --- a/lib/gitlab/analytics/cycle_analytics/data_collector.rb +++ b/lib/gitlab/analytics/cycle_analytics/data_collector.rb @@ -29,13 +29,13 @@ module Gitlab def median strong_memoize(:median) do - Median.new(stage: stage, query: query) + Median.new(stage: stage, query: query, params: params) end end def average strong_memoize(:average) do - Average.new(stage: stage, query: query) + Average.new(stage: stage, query: query, params: params) end end diff --git a/lib/gitlab/analytics/cycle_analytics/median.rb b/lib/gitlab/analytics/cycle_analytics/median.rb index 6c0450ac9e5..5775d0324c6 100644 --- a/lib/gitlab/analytics/cycle_analytics/median.rb +++ b/lib/gitlab/analytics/cycle_analytics/median.rb @@ -6,9 +6,10 @@ module Gitlab class Median include StageQueryHelpers - def initialize(stage:, query:) + def initialize(stage:, query:, params: {}) @stage = stage @query = query + @params = params end # rubocop: disable CodeReuse/ActiveRecord @@ -26,7 +27,7 @@ module Gitlab private - attr_reader :stage + attr_reader :stage, :params def percentile_cont percentile_cont_ordering = Arel::Nodes::UnaryOperation.new(Arel::Nodes::SqlLiteral.new('ORDER BY'), duration) diff --git a/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb b/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb index b4752ed9e5b..0b9102f0398 100644 --- a/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb +++ b/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb @@ -124,7 +124,7 @@ module Gitlab def time_columns [ stage.start_event.timestamp_projection.as('start_event_timestamp'), - stage.end_event.timestamp_projection.as('end_event_timestamp'), + end_event_timestamp_projection.as('end_event_timestamp'), round_duration_to_seconds.as('total_time') ] end diff --git a/lib/gitlab/analytics/cycle_analytics/sorting.rb b/lib/gitlab/analytics/cycle_analytics/sorting.rb index 828879d466d..c399bac423b 100644 --- a/lib/gitlab/analytics/cycle_analytics/sorting.rb +++ b/lib/gitlab/analytics/cycle_analytics/sorting.rb @@ -4,23 +4,35 @@ module Gitlab module Analytics module CycleAnalytics class Sorting + include StageQueryHelpers + + def initialize(stage:, query:, params: {}) + @stage = stage + @query = query + @params = params + end + # rubocop: disable CodeReuse/ActiveRecord - SORTING_OPTIONS = { - end_event: { - asc: -> (query, stage) { query.reorder(stage.end_event.timestamp_projection.asc) }, - desc: -> (query, stage) { query.reorder(stage.end_event.timestamp_projection.desc) } - }.freeze, - duration: { - asc: -> (query, stage) { query.reorder(Arel::Nodes::Subtraction.new(stage.end_event.timestamp_projection, stage.start_event.timestamp_projection).asc) }, - desc: -> (query, stage) { query.reorder(Arel::Nodes::Subtraction.new(stage.end_event.timestamp_projection, stage.start_event.timestamp_projection).desc) } - }.freeze - }.freeze - # rubocop: enable CodeReuse/ActiveRecord, + def apply(sort, direction) + sorting_options = { + end_event: { + asc: -> { query.reorder(end_event_timestamp_projection.asc) }, + desc: -> { query.reorder(end_event_timestamp_projection.desc) } + }, + duration: { + asc: -> { query.reorder(duration.asc) }, + desc: -> { query.reorder(duration.desc) } + } + } - def self.apply(query, stage, sort, direction) - sort_lambda = SORTING_OPTIONS.dig(sort, direction) || SORTING_OPTIONS.dig(:end_event, :desc) - sort_lambda.call(query, stage) + sort_lambda = sorting_options.dig(sort, direction) || sorting_options.dig(:end_event, :desc) + sort_lambda.call end + # rubocop: enable CodeReuse/ActiveRecord + + private + + attr_reader :stage, :query, :params end end end diff --git a/lib/gitlab/analytics/cycle_analytics/stage_events/metrics_based_stage_event.rb b/lib/gitlab/analytics/cycle_analytics/stage_events/metrics_based_stage_event.rb index 6f46b2a4180..fd30ab5277d 100644 --- a/lib/gitlab/analytics/cycle_analytics/stage_events/metrics_based_stage_event.rb +++ b/lib/gitlab/analytics/cycle_analytics/stage_events/metrics_based_stage_event.rb @@ -11,6 +11,12 @@ module Gitlab end # rubocop: enable CodeReuse/ActiveRecord + # rubocop: disable CodeReuse/ActiveRecord + def apply_negated_query_customization(query) + super.joins(:metrics) + end + # rubocop: enable CodeReuse/ActiveRecord + def column_list [timestamp_projection] end diff --git a/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event.rb b/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event.rb index 0fdc3c6681e..530e53f9d10 100644 --- a/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event.rb +++ b/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event.rb @@ -51,6 +51,12 @@ module Gitlab query end + # rubocop: disable CodeReuse/ActiveRecord + def apply_negated_query_customization(query) + query.where(timestamp_projection.eq(nil)) + end + # rubocop: enable CodeReuse/ActiveRecord + def self.label_based? false end diff --git a/lib/gitlab/analytics/cycle_analytics/stage_query_helpers.rb b/lib/gitlab/analytics/cycle_analytics/stage_query_helpers.rb index 777a8278e6e..11fe1dde12f 100644 --- a/lib/gitlab/analytics/cycle_analytics/stage_query_helpers.rb +++ b/lib/gitlab/analytics/cycle_analytics/stage_query_helpers.rb @@ -18,22 +18,30 @@ module Gitlab def duration Arel::Nodes::Subtraction.new( - stage.end_event.timestamp_projection, + end_event_timestamp_projection, stage.start_event.timestamp_projection ) end + def end_event_timestamp_projection + if in_progress? + Arel::Nodes::NamedFunction.new('TO_TIMESTAMP', [Time.current.to_i]) + else + stage.end_event.timestamp_projection + end + end + # rubocop: disable CodeReuse/ActiveRecord def order_by(query, sort, direction, extra_columns_to_select = [:id]) - ordered_query = Gitlab::Analytics::CycleAnalytics::Sorting.apply(query, stage, sort, direction) + ordered_query = Gitlab::Analytics::CycleAnalytics::Sorting.new(stage: stage, query: query, params: params).apply(sort, direction) # When filtering for more than one label, postgres requires the columns in ORDER BY to be present in the GROUP BY clause if requires_grouping? - column_list = [ - *extra_columns_to_select, - *stage.end_event.column_list, - *stage.start_event.column_list - ] + column_list = [].tap do |array| + array.concat(extra_columns_to_select) + array.concat(stage.end_event.column_list) unless in_progress? + array.concat(stage.start_event.column_list) + end ordered_query = ordered_query.group(column_list) end @@ -45,6 +53,10 @@ module Gitlab def requires_grouping? Array(params[:label_name]).size > 1 end + + def in_progress? + params[:end_event_filter] == :in_progress + end end end end |