diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-28 15:10:10 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-28 15:10:10 +0300 |
commit | 22fd199237e247c36de5b982d444cedc194126e6 (patch) | |
tree | 1a5ad68a1dffdf37dfae0d1267bf3bcc04c292cb /app/models | |
parent | 97b93f6d05b26e57a4d6a6d33a46aacb5f3235a6 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/concerns/counter_attribute.rb | 35 | ||||
-rw-r--r-- | app/models/integrations/base_chat_notification.rb | 13 | ||||
-rw-r--r-- | app/models/project_statistics.rb | 27 |
3 files changed, 49 insertions, 26 deletions
diff --git a/app/models/concerns/counter_attribute.rb b/app/models/concerns/counter_attribute.rb index 03e062a9855..4dfaae674bf 100644 --- a/app/models/concerns/counter_attribute.rb +++ b/app/models/concerns/counter_attribute.rb @@ -17,6 +17,18 @@ # counter_attribute :storage_size # end # +# It's possible to define a conditional counter attribute. You need to pass a proc +# that must accept a single argument, the object instance on which this concern is +# included. +# +# @example: +# +# class ProjectStatistics +# include CounterAttribute +# +# counter_attribute :conditional_one, if: -> { |object| object.use_counter_attribute? } +# end +# # To increment the counter we can use the method: # delayed_increment_counter(:commit_count, 3) # @@ -49,12 +61,15 @@ module CounterAttribute WORKER_LOCK_TTL = 10.minutes class_methods do - def counter_attribute(attribute) - counter_attributes << attribute + def counter_attribute(attribute, if: nil) + counter_attributes << { + attribute: attribute, + if_proc: binding.local_variable_get(:if) # can't read `if` directly + } end def counter_attributes - @counter_attributes ||= Set.new + @counter_attributes ||= [] end def after_flush_callbacks @@ -65,10 +80,14 @@ module CounterAttribute def counter_attribute_after_flush(&callback) after_flush_callbacks << callback end + end - def counter_attribute_enabled?(attribute) - counter_attributes.include?(attribute) - end + def counter_attribute_enabled?(attribute) + counter_attribute = self.class.counter_attributes.find { |registered| registered[:attribute] == attribute } + return false unless counter_attribute + return true unless counter_attribute[:if_proc] + + counter_attribute[:if_proc].call(self) end # This method must only be called by FlushCounterIncrementsWorker @@ -167,10 +186,6 @@ module CounterAttribute counter_key(attribute) + ':lock' end - def counter_attribute_enabled?(attribute) - self.class.counter_attribute_enabled?(attribute) - end - private def database_lock_key diff --git a/app/models/integrations/base_chat_notification.rb b/app/models/integrations/base_chat_notification.rb index c7ab9befd12..78d7dc60ed9 100644 --- a/app/models/integrations/base_chat_notification.rb +++ b/app/models/integrations/base_chat_notification.rb @@ -108,15 +108,13 @@ module Integrations end def execute(data) - return unless supported_events.include?(data[:object_kind]) - - return unless webhook.present? - object_kind = data[:object_kind] + return false unless should_execute?(object_kind) + data = custom_data(data) - return unless notify_label?(data) + return false unless notify_label?(data) # WebHook events often have an 'update' event that follows a 'open' or # 'close' action. Ignore update events for now to prevent duplicate @@ -182,6 +180,11 @@ module Integrations private + def should_execute?(object_kind) + supported_events.include?(object_kind) && + (!requires_webhook? || webhook.present?) + end + def log_usage(_, _) # Implement in child class end diff --git a/app/models/project_statistics.rb b/app/models/project_statistics.rb index 0570be85ad1..fb0ad178c91 100644 --- a/app/models/project_statistics.rb +++ b/app/models/project_statistics.rb @@ -11,6 +11,7 @@ class ProjectStatistics < ApplicationRecord attribute :snippets_size, default: 0 counter_attribute :build_artifacts_size + counter_attribute :packages_size, if: -> (statistics) { Feature.enabled?(:packages_size_counter_attribute, statistics.project) } counter_attribute_after_flush do |project_statistic| project_statistic.refresh_storage_size! @@ -22,7 +23,7 @@ class ProjectStatistics < ApplicationRecord COLUMNS_TO_REFRESH = [:repository_size, :wiki_size, :lfs_objects_size, :commit_count, :snippets_size, :uploads_size, :container_registry_size].freeze INCREMENTABLE_COLUMNS = { - packages_size: %i[storage_size], + packages_size: %i[storage_size], # remove this along with packages_size_counter_attribute pipeline_artifacts_size: %i[storage_size], snippets_size: %i[storage_size] }.freeze @@ -124,20 +125,20 @@ class ProjectStatistics < ApplicationRecord # # For non-counter attributes, storage_size is updated depending on key => [columns] in INCREMENTABLE_COLUMNS def self.increment_statistic(project, key, amount) - raise ArgumentError, "Cannot increment attribute: #{key}" unless incrementable_attribute?(key) - return if amount == 0 - project.statistics.try do |project_statistics| - if counter_attribute_enabled?(key) - project_statistics.delayed_increment_counter(key, amount) - else - project_statistics.legacy_increment_statistic(key, amount) - end + project_statistics.increment_statistic(key, amount) end end - def self.incrementable_attribute?(key) - INCREMENTABLE_COLUMNS.key?(key) || counter_attribute_enabled?(key) + def increment_statistic(key, amount) + raise ArgumentError, "Cannot increment attribute: #{key}" unless incrementable_attribute?(key) + return if amount == 0 + + if counter_attribute_enabled?(key) + delayed_increment_counter(key, amount) + else + legacy_increment_statistic(key, amount) + end end def legacy_increment_statistic(key, amount) @@ -149,6 +150,10 @@ class ProjectStatistics < ApplicationRecord private + def incrementable_attribute?(key) + INCREMENTABLE_COLUMNS.key?(key) || counter_attribute_enabled?(key) + end + def storage_size_components STORAGE_SIZE_COMPONENTS end |