Introduce enqueue_scheduled event

This commit is contained in:
Shinya Maeda 2018-09-24 20:02:26 +09:00 committed by Alessio Caiazza
parent f97ec4b8f4
commit 703a41f886
8 changed files with 47 additions and 53 deletions

View File

@ -22,7 +22,6 @@ module Ci
}.freeze
has_one :last_deployment, -> { order('deployments.id DESC') }, as: :deployable, class_name: 'Deployment'
has_one :build_schedule, class_name: 'Ci::BuildSchedule', foreign_key: :build_id
has_many :trace_sections, class_name: 'Ci::BuildTraceSection'
has_many :trace_chunks, class_name: 'Ci::BuildTraceChunk', foreign_key: :build_id
@ -168,12 +167,26 @@ module Ci
transition scheduled: :manual
end
before_transition created: :scheduled do |build|
build.build_build_schedule(execute_at: build.execute_at)
event :enqueue_scheduled do
transition scheduled: :pending do
validate do |build|
build.scheduled_at && build.scheduled_at < Time.now
end
end
end
before_transition scheduled: any do |build|
build.build_schedule.delete
build.scheduled_at = nil
end
before_transition created: :scheduled do |build|
build.scheduled_at = build.get_scheduled_at
end
after_transition created: :scheduled do |build|
build.run_after_commit do
Ci::BuildScheduleWorker.perform_at(build.scheduled_at, build.id)
end
end
after_transition any => [:pending] do |build|
@ -250,7 +263,7 @@ module Ci
self.when == 'delayed' && options[:start_in].present?
end
def execute_at
def get_scheduled_at
ChronicDuration.parse(options[:start_in])&.seconds&.from_now
end

View File

@ -1,35 +0,0 @@
# frozen_string_literal: true
module Ci
class BuildSchedule < ActiveRecord::Base
extend Gitlab::Ci::Model
include Importable
include AfterCommitQueue
belongs_to :build
validate :schedule_at_future
after_create :schedule, unless: :importing?
scope :stale, -> { where("execute_at < ?", Time.now) }
def execute_in
[0, self.execute_at - Time.now].max
end
private
def schedule_at_future
if self.execute_at < Time.now
errors.add(:execute_at, "Excute point must be somewhere in the future")
end
end
def schedule
run_after_commit do
Ci::BuildScheduleWorker.perform_at(self.execute_at, self.build_id)
end
end
end
end

View File

@ -35,6 +35,10 @@ module Ci
"#{subject.name} - #{detailed_status.status_tooltip}"
end
def execute_in
[0, scheduled_at - Time.now].max
end
private
def tooltip_for_badge

View File

@ -0,0 +1,13 @@
# frozen_string_literal: true
module Ci
class RunScheduledBuildService < ::BaseService
def execute(build)
unless can?(current_user, :update_build, build)
raise Gitlab::Access::AccessDeniedError
end
build.enqueue_scheduled!
end
end
end

View File

@ -104,9 +104,9 @@
- elsif job.scheduled?
.btn-group
.btn.btn-default.has-tooltip{ disabled: true,
title: job.build_schedule.execute_at }
title: job.scheduled_at }
= sprite_icon('planning')
= duration_in_numbers(job.build_schedule.execute_in)
= duration_in_numbers(job.execute_in)
.btn.btn-default.btn-build.has-tooltip{ title: s_('DelayedJobs|Start now') }
= sprite_icon('play')
.btn.btn-default.btn-build.has-tooltip{ title: s_('DelayedJobs|Unschedule') }

View File

@ -6,10 +6,9 @@ module Ci
include PipelineQueue
def perform(build_id)
::Ci::Build.find_by(id: build_id).try do |build|
break unless build.scheduled?
Ci::PlayBuildService.new(build.project, build.user).execute(build)
::Ci::Build.find_by_id(build_id).try do |build|
Ci::RunScheduledBuildService
.new(build.project, build.user).execute(build)
end
end
end

View File

@ -23,7 +23,7 @@ module Gitlab
private
def execute_in
Time.at(subject.build_schedule.execute_in).utc.strftime("%H:%M:%S")
Time.at(subject.scheduled_at).utc.strftime("%H:%M:%S")
end
end
end

View File

@ -64,15 +64,15 @@ cleanup:
#
# ### Reproduce the scenario ~ when all stages succeeded ~
#
# 1. ScheduledJobFixture.new(29, 1).create_pipeline('master')
# 1. ScheduledJobFixture.new(29, 1).finish_stage_until('test')
# 1. ScheduledJobFixture.new(16, 1).create_pipeline('master')
# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('test')
# 1. Wait until rollout 10% job is triggered
# 1. ScheduledJobFixture.new(29, 1).finish_stage_until('rollout 10%')
# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('rollout 10%')
# 1. Wait until rollout 50% job is triggered
# 1. ScheduledJobFixture.new(29, 1).finish_stage_until('rollout 50%')
# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('rollout 50%')
# 1. Wait until rollout 100% job is triggered
# 1. ScheduledJobFixture.new(29, 1).finish_stage_until('rollout 100%')
# 1. ScheduledJobFixture.new(29, 1).finish_stage_until('cleanup')
# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('rollout 100%')
# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('cleanup')
#
# Expectation: Users see a succeccful pipeline
#