diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-03-18 23:02:30 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-03-18 23:02:30 +0300 |
commit | 41fe97390ceddf945f3d967b8fdb3de4c66b7dea (patch) | |
tree | 9c8d89a8624828992f06d892cd2f43818ff5dcc8 /app/models/projects | |
parent | 0804d2dc31052fb45a1efecedc8e06ce9bc32862 (diff) |
Add latest changes from gitlab-org/gitlab@14-9-stable-eev14.9.0-rc42
Diffstat (limited to 'app/models/projects')
-rw-r--r-- | app/models/projects/build_artifacts_size_refresh.rb | 91 | ||||
-rw-r--r-- | app/models/projects/topic.rb | 7 | ||||
-rw-r--r-- | app/models/projects/triggered_hooks.rb | 25 |
3 files changed, 120 insertions, 3 deletions
diff --git a/app/models/projects/build_artifacts_size_refresh.rb b/app/models/projects/build_artifacts_size_refresh.rb new file mode 100644 index 00000000000..afb67b79f0d --- /dev/null +++ b/app/models/projects/build_artifacts_size_refresh.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true + +module Projects + class BuildArtifactsSizeRefresh < ApplicationRecord + include BulkInsertSafe + + STALE_WINDOW = 3.days + + self.table_name = 'project_build_artifacts_size_refreshes' + + belongs_to :project + + validates :project, presence: true + + STATES = { + created: 1, + running: 2, + pending: 3 + }.freeze + + state_machine :state, initial: :created do + # created -> running <-> pending + state :created, value: STATES[:created] + state :running, value: STATES[:running] + state :pending, value: STATES[:pending] + + event :process do + transition [:created, :pending, :running] => :running + end + + event :requeue do + transition running: :pending + end + + # set it only the first time we execute the refresh + before_transition created: :running do |refresh| + refresh.reset_project_statistics! + refresh.refresh_started_at = Time.zone.now + end + + before_transition running: any do |refresh, transition| + refresh.updated_at = Time.zone.now + end + + before_transition running: :pending do |refresh, transition| + refresh.last_job_artifact_id = transition.args.first + end + end + + scope :stale, -> { with_state(:running).where('updated_at < ?', STALE_WINDOW.ago) } + scope :remaining, -> { with_state(:created, :pending).or(stale) } + + def self.enqueue_refresh(projects) + now = Time.zone.now + + records = Array(projects).map do |project| + new(project: project, state: STATES[:created], created_at: now, updated_at: now) + end + + bulk_insert!(records, skip_duplicates: true) + end + + def self.process_next_refresh! + next_refresh = nil + + transaction do + next_refresh = remaining + .order(:state, :updated_at) + .lock('FOR UPDATE SKIP LOCKED') + .take + + next_refresh&.process! + end + + next_refresh + end + + def reset_project_statistics! + statistics = project.statistics + statistics.update!(build_artifacts_size: 0) + statistics.clear_counter!(:build_artifacts_size) + end + + def next_batch(limit:) + project.job_artifacts.select(:id, :size) + .where('created_at <= ? AND id > ?', refresh_started_at, last_job_artifact_id.to_i) + .order(:created_at) + .limit(limit) + end + end +end diff --git a/app/models/projects/topic.rb b/app/models/projects/topic.rb index 78bc2df2e1e..b42b03f0618 100644 --- a/app/models/projects/topic.rb +++ b/app/models/projects/topic.rb @@ -7,18 +7,19 @@ module Projects include Avatarable include Gitlab::SQL::Pattern - validates :name, presence: true, uniqueness: true, length: { maximum: 255 } + validates :name, presence: true, length: { maximum: 255 } + validates :name, uniqueness: { case_sensitive: false }, if: :name_changed? validates :description, length: { maximum: 1024 } has_many :project_topics, class_name: 'Projects::ProjectTopic' has_many :projects, through: :project_topics - scope :order_by_total_projects_count, -> { order(total_projects_count: :desc).order(id: :asc) } + scope :order_by_non_private_projects_count, -> { order(non_private_projects_count: :desc).order(id: :asc) } scope :reorder_by_similarity, -> (search) do order_expression = Gitlab::Database::SimilarityScore.build_expression(search: search, rules: [ { column: arel_table['name'] } ]) - reorder(order_expression.desc, arel_table['total_projects_count'].desc, arel_table['id']) + reorder(order_expression.desc, arel_table['non_private_projects_count'].desc, arel_table['id']) end class << self diff --git a/app/models/projects/triggered_hooks.rb b/app/models/projects/triggered_hooks.rb new file mode 100644 index 00000000000..e3aa3d106b7 --- /dev/null +++ b/app/models/projects/triggered_hooks.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Projects + class TriggeredHooks + def initialize(scope, data) + @scope = scope + @data = data + @relations = [] + end + + def add_hooks(relation) + @relations << relation + self + end + + def execute + # Assumes that the relations implement TriggerableHooks + @relations.each do |hooks| + hooks.hooks_for(@scope).select_active(@scope, @data).each do |hook| + hook.async_execute(@data, @scope.to_s) + end + end + end + end +end |