blob: bde75e12295574750d0d358b3e7528e7baeaa68a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
|