2016-08-29 08:24:48 -04:00
|
|
|
module Gitlab
|
|
|
|
module Ci
|
|
|
|
class PipelineDuration
|
2016-08-30 11:06:29 -04:00
|
|
|
PeriodStruct = Struct.new(:first, :last)
|
2016-08-30 11:11:57 -04:00
|
|
|
class Period < PeriodStruct
|
2016-08-29 08:24:48 -04:00
|
|
|
def duration
|
|
|
|
last - first
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.from_builds(builds)
|
|
|
|
now = Time.now
|
|
|
|
|
2016-08-30 11:06:29 -04:00
|
|
|
periods = builds.map do |b|
|
|
|
|
Period.new(b.started_at || now, b.finished_at || now)
|
2016-08-29 08:24:48 -04:00
|
|
|
end
|
|
|
|
|
2016-08-30 11:06:29 -04:00
|
|
|
new(periods)
|
2016-08-29 08:24:48 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
attr_reader :duration, :pending_duration
|
|
|
|
|
2016-08-30 11:06:29 -04:00
|
|
|
def initialize(periods)
|
|
|
|
process(periods.sort_by(&:first))
|
2016-08-29 08:24:48 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2016-08-30 11:06:29 -04:00
|
|
|
def process(periods)
|
|
|
|
merged = process_periods(periods)
|
2016-08-29 08:24:48 -04:00
|
|
|
|
|
|
|
@duration = process_duration(merged)
|
2016-08-30 11:08:25 -04:00
|
|
|
@pending_duration = process_pending_duration(merged)
|
2016-08-29 08:24:48 -04:00
|
|
|
end
|
|
|
|
|
2016-08-30 11:06:29 -04:00
|
|
|
def process_periods(periods)
|
|
|
|
if periods.empty?
|
|
|
|
periods
|
2016-08-29 08:24:48 -04:00
|
|
|
else
|
2016-08-30 11:06:29 -04:00
|
|
|
periods.drop(1).inject([periods.first]) do |result, current|
|
|
|
|
merged = try_merge_period(result.last, current)
|
2016-08-29 08:24:48 -04:00
|
|
|
|
2016-08-30 11:02:39 -04:00
|
|
|
if merged
|
|
|
|
result[-1] = merged
|
2016-08-29 08:24:48 -04:00
|
|
|
result
|
2016-08-30 11:02:39 -04:00
|
|
|
else
|
|
|
|
result << current
|
2016-08-29 08:24:48 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-08-30 11:06:29 -04:00
|
|
|
def try_merge_period(previous, current)
|
2016-08-30 11:02:39 -04:00
|
|
|
if current.first <= previous.last
|
2016-08-30 11:06:29 -04:00
|
|
|
Period.new(previous.first, [previous.last, current.last].max)
|
2016-08-29 08:24:48 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-08-30 11:06:29 -04:00
|
|
|
def process_duration(periods)
|
|
|
|
periods.inject(0) do |result, per|
|
|
|
|
result + per.duration
|
2016-08-29 08:24:48 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-08-30 11:08:25 -04:00
|
|
|
def process_pending_duration(periods)
|
2016-08-30 11:06:29 -04:00
|
|
|
return 0 if periods.empty?
|
2016-08-29 11:40:15 -04:00
|
|
|
|
2016-08-30 11:06:29 -04:00
|
|
|
total = periods.last.last - periods.first.first
|
2016-08-29 08:24:48 -04:00
|
|
|
total - duration
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|