Commit 703a41f8 authored by Shinya Maeda's avatar Shinya Maeda Committed by Alessio Caiazza

Introduce enqueue_scheduled event

parent f97ec4b8
...@@ -22,7 +22,6 @@ module Ci ...@@ -22,7 +22,6 @@ module Ci
}.freeze }.freeze
has_one :last_deployment, -> { order('deployments.id DESC') }, as: :deployable, class_name: 'Deployment' 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_sections, class_name: 'Ci::BuildTraceSection'
has_many :trace_chunks, class_name: 'Ci::BuildTraceChunk', foreign_key: :build_id has_many :trace_chunks, class_name: 'Ci::BuildTraceChunk', foreign_key: :build_id
...@@ -168,12 +167,26 @@ module Ci ...@@ -168,12 +167,26 @@ module Ci
transition scheduled: :manual transition scheduled: :manual
end end
before_transition created: :scheduled do |build| event :enqueue_scheduled do
build.build_build_schedule(execute_at: build.execute_at) transition scheduled: :pending do
validate do |build|
build.scheduled_at && build.scheduled_at < Time.now
end
end
end end
before_transition scheduled: any do |build| 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 end
after_transition any => [:pending] do |build| after_transition any => [:pending] do |build|
...@@ -250,7 +263,7 @@ module Ci ...@@ -250,7 +263,7 @@ module Ci
self.when == 'delayed' && options[:start_in].present? self.when == 'delayed' && options[:start_in].present?
end end
def execute_at def get_scheduled_at
ChronicDuration.parse(options[:start_in])&.seconds&.from_now ChronicDuration.parse(options[:start_in])&.seconds&.from_now
end end
......
# 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
...@@ -35,6 +35,10 @@ module Ci ...@@ -35,6 +35,10 @@ module Ci
"#{subject.name} - #{detailed_status.status_tooltip}" "#{subject.name} - #{detailed_status.status_tooltip}"
end end
def execute_in
[0, scheduled_at - Time.now].max
end
private private
def tooltip_for_badge def tooltip_for_badge
......
# 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
...@@ -104,9 +104,9 @@ ...@@ -104,9 +104,9 @@
- elsif job.scheduled? - elsif job.scheduled?
.btn-group .btn-group
.btn.btn-default.has-tooltip{ disabled: true, .btn.btn-default.has-tooltip{ disabled: true,
title: job.build_schedule.execute_at } title: job.scheduled_at }
= sprite_icon('planning') = 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') } .btn.btn-default.btn-build.has-tooltip{ title: s_('DelayedJobs|Start now') }
= sprite_icon('play') = sprite_icon('play')
.btn.btn-default.btn-build.has-tooltip{ title: s_('DelayedJobs|Unschedule') } .btn.btn-default.btn-build.has-tooltip{ title: s_('DelayedJobs|Unschedule') }
......
...@@ -6,10 +6,9 @@ module Ci ...@@ -6,10 +6,9 @@ module Ci
include PipelineQueue include PipelineQueue
def perform(build_id) def perform(build_id)
::Ci::Build.find_by(id: build_id).try do |build| ::Ci::Build.find_by_id(build_id).try do |build|
break unless build.scheduled? Ci::RunScheduledBuildService
.new(build.project, build.user).execute(build)
Ci::PlayBuildService.new(build.project, build.user).execute(build)
end end
end end
end end
......
...@@ -23,7 +23,7 @@ module Gitlab ...@@ -23,7 +23,7 @@ module Gitlab
private private
def execute_in 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 end
end end
......
...@@ -64,15 +64,15 @@ cleanup: ...@@ -64,15 +64,15 @@ cleanup:
# #
# ### Reproduce the scenario ~ when all stages succeeded ~ # ### Reproduce the scenario ~ when all stages succeeded ~
# #
# 1. ScheduledJobFixture.new(29, 1).create_pipeline('master') # 1. ScheduledJobFixture.new(16, 1).create_pipeline('master')
# 1. ScheduledJobFixture.new(29, 1).finish_stage_until('test') # 1. ScheduledJobFixture.new(16, 1).finish_stage_until('test')
# 1. Wait until rollout 10% job is triggered # 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. 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. Wait until rollout 100% job is triggered
# 1. ScheduledJobFixture.new(29, 1).finish_stage_until('rollout 100%') # 1. ScheduledJobFixture.new(16, 1).finish_stage_until('rollout 100%')
# 1. ScheduledJobFixture.new(29, 1).finish_stage_until('cleanup') # 1. ScheduledJobFixture.new(16, 1).finish_stage_until('cleanup')
# #
# Expectation: Users see a succeccful pipeline # Expectation: Users see a succeccful pipeline
# #
......
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