From d071f61b0de12a57012ed1c77634b54fa83615a7 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 5 Sep 2016 17:55:30 +0800 Subject: Forget about pending duration for now, need more discussion --- app/models/ci/pipeline.rb | 3 +- ...0829122117_add_pending_duration_to_pipelines.rb | 7 ---- db/schema.rb | 1 - lib/gitlab/ci/pipeline_duration.rb | 49 +++++----------------- 4 files changed, 11 insertions(+), 49 deletions(-) delete mode 100644 db/migrate/20160829122117_add_pending_duration_to_pipelines.rb diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index de7709c36c4..4092205578e 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -260,8 +260,7 @@ module Ci def update_duration return unless started_at - self.duration, self.pending_duration = - Gitlab::Ci::PipelineDuration.from_pipeline(self) + self.duration = Gitlab::Ci::PipelineDuration.from_pipeline(self) end def execute_hooks diff --git a/db/migrate/20160829122117_add_pending_duration_to_pipelines.rb b/db/migrate/20160829122117_add_pending_duration_to_pipelines.rb deleted file mode 100644 index 6f238a2f65c..00000000000 --- a/db/migrate/20160829122117_add_pending_duration_to_pipelines.rb +++ /dev/null @@ -1,7 +0,0 @@ -class AddPendingDurationToPipelines < ActiveRecord::Migration - DOWNTIME = false - - def change - add_column :ci_commits, :pending_duration, :integer - end -end diff --git a/db/schema.rb b/db/schema.rb index f57c4149e6c..af6e74a4e25 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -210,7 +210,6 @@ ActiveRecord::Schema.define(version: 20160831223750) do t.datetime "finished_at" t.integer "duration" t.integer "user_id" - t.integer "pending_duration" end add_index "ci_commits", ["gl_project_id", "sha"], name: "index_ci_commits_on_gl_project_id_and_sha", using: :btree diff --git a/lib/gitlab/ci/pipeline_duration.rb b/lib/gitlab/ci/pipeline_duration.rb index ac68fd0272f..cd782934302 100644 --- a/lib/gitlab/ci/pipeline_duration.rb +++ b/lib/gitlab/ci/pipeline_duration.rb @@ -1,11 +1,14 @@ module Gitlab module Ci + # # Introduction - total running time + # # The problem this class is trying to solve is finding the total running # time amongst all the jobs, excluding retries and pending (queue) time. # We could reduce this problem down to finding the union of periods. # # 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) # * B (2, 4) @@ -24,22 +27,7 @@ module Gitlab # # (4 - 1) + (7 - 6) => 4 # - # And the pending (queue) time would be (4, 6) like this: (marked as X) - # - # 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 # # The algorithm used here for union would be described as follow. # First we make sure that all periods are sorted by `Period#first`. @@ -82,22 +70,12 @@ module Gitlab # `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. # - # After having the union of all periods, the rest is simple and - # described in the beginning. To summarise: - # - # 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: + # After having the union of all periods, we just need to sum the length + # of all periods to get total time. # - # 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 - # but not here because here we try not to be depending on pipeline - # and it's trivial enough to get that information. + # That is 4 is the answer in the example. class PipelineDuration PeriodStruct = Struct.new(:first, :last) class Period < PeriodStruct @@ -107,17 +85,10 @@ module Gitlab end def self.from_pipeline(pipeline) - now = Time.now status = %w[success failed running canceled] builds = pipeline.builds.latest.where(status: status) - running = from_builds(builds, :started_at, :finished_at, now).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] + from_builds(builds, :started_at, :finished_at).duration end def self.from_builds(builds, from, to, now = Time.now) -- cgit v1.2.1