Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/database/async_indexes/index_base.rb')
-rw-r--r--lib/gitlab/database/async_indexes/index_base.rb90
1 files changed, 90 insertions, 0 deletions
diff --git a/lib/gitlab/database/async_indexes/index_base.rb b/lib/gitlab/database/async_indexes/index_base.rb
new file mode 100644
index 00000000000..bde75e12295
--- /dev/null
+++ b/lib/gitlab/database/async_indexes/index_base.rb
@@ -0,0 +1,90 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module AsyncIndexes
+ class IndexBase
+ include AsyncDdlExclusiveLeaseGuard
+ extend ::Gitlab::Utils::Override
+
+ TIMEOUT_PER_ACTION = 1.day
+
+ def initialize(async_index)
+ @async_index = async_index
+ end
+
+ def perform
+ try_obtain_lease do
+ if preconditions_met?
+ log_index_info("Starting async index #{action_type}")
+ execute_action_with_error_handling
+ log_index_info("Finished async index #{action_type}")
+ else
+ log_index_info(skip_log_message)
+ async_index.destroy!
+ end
+ end
+ end
+
+ private
+
+ attr_reader :async_index
+
+ delegate :connection, :connection_db_config, to: :async_index
+
+ def preconditions_met?
+ raise NotImplementedError, 'must implement preconditions_met?'
+ end
+
+ def action_type
+ raise NotImplementedError, 'must implement action_type'
+ end
+
+ def execute_action_with_error_handling
+ around_execution { execute_action }
+ rescue StandardError => error
+ async_index.handle_exception!(error)
+
+ Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error)
+ Gitlab::AppLogger.error(message: error.message, **logging_options)
+ end
+
+ def around_execution
+ yield
+ end
+
+ def execute_action
+ connection.execute(async_index.definition)
+ async_index.destroy!
+ end
+
+ def index_exists?
+ connection.indexes(async_index.table_name).any? do |index|
+ index.name == async_index.name
+ end
+ end
+
+ def lease_timeout
+ TIMEOUT_PER_ACTION
+ end
+
+ def log_index_info(message)
+ Gitlab::AppLogger.info(message: message, **logging_options)
+ end
+
+ def skip_log_message
+ "Skipping index #{action_type} since preconditions are not met. " \
+ "The queuing entry will be deleted"
+ end
+
+ def logging_options
+ {
+ table_name: async_index.table_name,
+ index_name: async_index.name,
+ class: self.class.name.to_s
+ }
+ end
+ end
+ end
+ end
+end