Commit d071f61b authored by Lin Jen-Shin's avatar Lin Jen-Shin

Forget about pending duration for now, need more discussion

parent 7aaed299
...@@ -260,8 +260,7 @@ module Ci ...@@ -260,8 +260,7 @@ module Ci
def update_duration def update_duration
return unless started_at return unless started_at
self.duration, self.pending_duration = self.duration = Gitlab::Ci::PipelineDuration.from_pipeline(self)
Gitlab::Ci::PipelineDuration.from_pipeline(self)
end end
def execute_hooks def execute_hooks
......
class AddPendingDurationToPipelines < ActiveRecord::Migration
DOWNTIME = false
def change
add_column :ci_commits, :pending_duration, :integer
end
end
...@@ -210,7 +210,6 @@ ActiveRecord::Schema.define(version: 20160831223750) do ...@@ -210,7 +210,6 @@ ActiveRecord::Schema.define(version: 20160831223750) do
t.datetime "finished_at" t.datetime "finished_at"
t.integer "duration" t.integer "duration"
t.integer "user_id" t.integer "user_id"
t.integer "pending_duration"
end end
add_index "ci_commits", ["gl_project_id", "sha"], name: "index_ci_commits_on_gl_project_id_and_sha", using: :btree add_index "ci_commits", ["gl_project_id", "sha"], name: "index_ci_commits_on_gl_project_id_and_sha", using: :btree
......
module Gitlab module Gitlab
module Ci module Ci
# # Introduction - total running time
#
# The problem this class is trying to solve is finding the total running # The problem this class is trying to solve is finding the total running
# time amongst all the jobs, excluding retries and pending (queue) time. # time amongst all the jobs, excluding retries and pending (queue) time.
# We could reduce this problem down to finding the union of periods. # We could reduce this problem down to finding the union of periods.
# #
# So each job would be represented as a `Period`, which consists of # So each job would be represented as a `Period`, which consists of
# `Period#first` and `Period#last`. A simple example here would be: # `Period#first` as when the job started and `Period#last` as when the
# job was finished. A simple example here would be:
# #
# * A (1, 3) # * A (1, 3)
# * B (2, 4) # * B (2, 4)
...@@ -24,22 +27,7 @@ module Gitlab ...@@ -24,22 +27,7 @@ module Gitlab
# #
# (4 - 1) + (7 - 6) => 4 # (4 - 1) + (7 - 6) => 4
# #
# And the pending (queue) time would be (4, 6) like this: (marked as X) # # The Algorithm
#
# 0 1 2 3 4 5 6 7
# AAAAAAA
# BBBBBBB
# CCCC
# XXXXX
#
# Which could be calculated by having (1, 7) as total time, minus
# the running time we have above, 4. The full calculation would be:
#
# total = (7 - 1)
# duration = (4 - 1) + (7 - 6)
# pending = total - duration # 6 - 4 => 2
#
# Which the answer to pending would be 2 in this example.
# #
# The algorithm used here for union would be described as follow. # The algorithm used here for union would be described as follow.
# First we make sure that all periods are sorted by `Period#first`. # First we make sure that all periods are sorted by `Period#first`.
...@@ -82,22 +70,12 @@ module Gitlab ...@@ -82,22 +70,12 @@ module Gitlab
# `C.first <= D.last` is `false`. Therefore we need to keep both C # `C.first <= D.last` is `false`. Therefore we need to keep both C
# and D. The example would end here because there are no more jobs. # and D. The example would end here because there are no more jobs.
# #
# After having the union of all periods, the rest is simple and # After having the union of all periods, we just need to sum the length
# described in the beginning. To summarise: # of all periods to get total time.
#
# duration = (4 - 1) + (7 - 6)
# total = (7 - 1)
# pending = total - duration # 6 - 4 => 2
#
# Note that the pending time is actually not the final pending time
# for pipelines, because we still need to accumulate the pending time
# before the first job (A in this example) even started! That is:
# #
# total_pending = pipeline.started_at - pipeline.created_at + pending # (4 - 1) + (7 - 6) => 4
# #
# Would be the final answer. We deal with that in pipeline itself # That is 4 is the answer in the example.
# but not here because here we try not to be depending on pipeline
# and it's trivial enough to get that information.
class PipelineDuration class PipelineDuration
PeriodStruct = Struct.new(:first, :last) PeriodStruct = Struct.new(:first, :last)
class Period < PeriodStruct class Period < PeriodStruct
...@@ -107,17 +85,10 @@ module Gitlab ...@@ -107,17 +85,10 @@ module Gitlab
end end
def self.from_pipeline(pipeline) def self.from_pipeline(pipeline)
now = Time.now
status = %w[success failed running canceled] status = %w[success failed running canceled]
builds = pipeline.builds.latest.where(status: status) builds = pipeline.builds.latest.where(status: status)
running = from_builds(builds, :started_at, :finished_at, now).duration from_builds(builds, :started_at, :finished_at).duration
pending = pipeline.started_at - pipeline.created_at
queuing = builds.inject(0) do |result, job|
result + ((job.started_at || now) - (job.queued_at || now))
end
[running, pending + queuing]
end end
def self.from_builds(builds, from, to, now = Time.now) def self.from_builds(builds, from, to, now = Time.now)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment