blob: fd01602c2568440a403898b9aba6aa5a13c882cb (
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
|
module Gitlab
module Verify
class BatchVerifier
attr_reader :batch_size, :start, :finish
def initialize(batch_size:, start: nil, finish: nil)
@batch_size = batch_size
@start = start
@finish = finish
end
# Yields a Range of IDs and a Hash of failed verifications (object => error)
def run_batches(&blk)
relation.in_batches(of: batch_size, start: start, finish: finish) do |relation| # rubocop: disable Cop/InBatches
range = relation.first.id..relation.last.id
failures = run_batch(relation)
yield(range, failures)
end
end
def name
raise NotImplementedError.new
end
def describe(_object)
raise NotImplementedError.new
end
private
def run_batch(relation)
relation.map { |upload| verify(upload) }.compact.to_h
end
def verify(object)
if local?(object)
verify_local(object)
else
verify_remote(object)
end
nil
rescue => err
[object, err]
end
def verify_local(object)
expected = expected_checksum(object)
actual = actual_checksum(object)
raise 'Checksum missing' unless expected.present?
raise 'Checksum mismatch' unless expected == actual
end
# We don't calculate checksum for remote objects, so just check existence
def verify_remote(object)
raise 'Remote object does not exist' unless object.build_uploader.exists?
end
# This should return an ActiveRecord::Relation suitable for calling #in_batches on
def relation
raise NotImplementedError.new
end
# Should return true if the object is stored locally
def local?(_object)
raise NotImplementedError.new
end
# The checksum we expect the object to have
def expected_checksum(_object)
raise NotImplementedError.new
end
# The freshly-recalculated checksum of the object
def actual_checksum(_object)
raise NotImplementedError.new
end
end
end
end
|