debian-mirror-gitlab/app/models/concerns/ci/partitionable.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

113 lines
3 KiB
Ruby
Raw Normal View History

2022-10-11 01:57:18 +05:30
# frozen_string_literal: true
module Ci
##
2023-06-20 00:43:36 +05:30
# This module implements a way to set the `partition_id` value on a dependent
2022-10-11 01:57:18 +05:30
# resource from a parent record.
# Usage:
#
# class PipelineVariable < Ci::ApplicationRecord
# include Ci::Partitionable
#
# belongs_to :pipeline
# partitionable scope: :pipeline
# # Or
# partitionable scope: ->(record) { record.partition_value }
#
#
module Partitionable
extend ActiveSupport::Concern
include ::Gitlab::Utils::StrongMemoize
2022-11-25 23:54:43 +05:30
module Testing
InclusionError = Class.new(StandardError)
PARTITIONABLE_MODELS = %w[
CommitStatus
Ci::BuildMetadata
2023-03-04 22:38:38 +05:30
Ci::BuildNeed
Ci::BuildReportResult
Ci::BuildRunnerSession
Ci::BuildTraceChunk
Ci::BuildTraceMetadata
Ci::BuildPendingState
2022-11-25 23:54:43 +05:30
Ci::JobArtifact
2023-03-04 22:38:38 +05:30
Ci::JobVariable
2022-11-25 23:54:43 +05:30
Ci::Pipeline
2023-03-04 22:38:38 +05:30
Ci::PendingBuild
Ci::RunningBuild
2023-06-20 00:43:36 +05:30
Ci::RunnerManagerBuild
2023-03-04 22:38:38 +05:30
Ci::PipelineVariable
Ci::Sources::Pipeline
Ci::Stage
Ci::UnitTestFailure
2022-11-25 23:54:43 +05:30
].freeze
def self.check_inclusion(klass)
return if PARTITIONABLE_MODELS.include?(klass.name)
raise Partitionable::Testing::InclusionError,
"#{klass} must be included in PARTITIONABLE_MODELS"
rescue InclusionError => e
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e)
end
end
2022-10-11 01:57:18 +05:30
included do
2022-11-25 23:54:43 +05:30
Partitionable::Testing.check_inclusion(self)
2022-10-11 01:57:18 +05:30
before_validation :set_partition_id, on: :create
validates :partition_id, presence: true
def set_partition_id
return if partition_id_changed? && partition_id.present?
return unless partition_scope_value
self.partition_id = partition_scope_value
end
end
class_methods do
2023-03-04 22:38:38 +05:30
def partitionable(scope:, through: nil, partitioned: false)
handle_partitionable_through(through)
handle_partitionable_scope(scope)
2023-05-27 22:25:52 +05:30
handle_partitionable_ddl(partitioned)
2023-03-04 22:38:38 +05:30
end
2023-01-13 00:05:48 +05:30
2023-03-04 22:38:38 +05:30
private
def handle_partitionable_through(options)
return unless options
define_singleton_method(:routing_table_name) { options[:table] }
define_singleton_method(:routing_table_name_flag) { options[:flag] }
include Partitionable::Switch
end
def handle_partitionable_scope(scope)
2022-10-11 01:57:18 +05:30
define_method(:partition_scope_value) do
strong_memoize(:partition_scope_value) do
2022-11-25 23:54:43 +05:30
next Ci::Pipeline.current_partition_value if respond_to?(:importing?) && importing?
2022-10-11 01:57:18 +05:30
record = scope.to_proc.call(self)
record.respond_to?(:partition_id) ? record.partition_id : record
end
end
end
2023-05-27 22:25:52 +05:30
def handle_partitionable_ddl(partitioned)
return unless partitioned
include ::PartitionedTable
partitioned_by :partition_id,
strategy: :ci_sliding_list,
next_partition_if: proc { false },
detach_partition_if: proc { false }
end
2022-10-11 01:57:18 +05:30
end
end
end