blob: 55d870e2e9dffe3e005b1b9dffbd4b80ccadb209 (
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
|
module Gitlab
module Ci
class PipelineDuration
PeriodStruct = Struct.new(:first, :last)
class Period < PeriodStruct
def duration
last - first
end
end
def self.from_builds(builds)
now = Time.now
periods = builds.map do |b|
Period.new(b.started_at || now, b.finished_at || now)
end
new(periods)
end
attr_reader :duration, :pending_duration
def initialize(periods)
process(periods.sort_by(&:first))
end
private
def process(periods)
merged = process_periods(periods)
@duration = process_duration(merged)
@pending_duration = process_pending_duration(merged)
end
def process_periods(periods)
if periods.empty?
periods
else
periods.drop(1).inject([periods.first]) do |result, current|
merged = try_merge_period(result.last, current)
if merged
result[-1] = merged
result
else
result << current
end
end
end
end
def try_merge_period(previous, current)
if current.first <= previous.last
Period.new(previous.first, [previous.last, current.last].max)
end
end
def process_duration(periods)
periods.inject(0) do |result, per|
result + per.duration
end
end
def process_pending_duration(periods)
return 0 if periods.empty?
total = periods.last.last - periods.first.first
total - duration
end
end
end
end
|