91 lines
2.3 KiB
Ruby
91 lines
2.3 KiB
Ruby
|
# 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
|