Commit 063a8c8c authored by Grzegorz Bizon's avatar Grzegorz Bizon

Add queue push/pop methods to build queue service

parent 65e2046e
......@@ -294,18 +294,20 @@ module Ci
end
end
after_transition any => [:pending] do |build|
Ci::UpdateBuildQueueService.new.queue_push!(build)
# rubocop:disable CodeReuse/ServiceClass
after_transition any => [:pending] do |build, transition|
Ci::UpdateBuildQueueService.new.push(build, transition)
build.run_after_commit do
BuildQueueWorker.perform_async(id)
end
end
after_transition pending: any do |build|
after_transition pending: any do |build, transition|
# TODO ensure that there is no race condition here, add test for this
Ci::UpdateBuildQueueService.new.queue_pop!(build)
Ci::UpdateBuildQueueService.new.pop(build, transition)
end
# rubocop:enable CodeReuse/ServiceClass
after_transition pending: :running do |build|
build.deployment&.run
......
......@@ -2,45 +2,50 @@
module Ci
class UpdateBuildQueueService
InvalidQueueTransition = Class.new(StandardError)
attr_reader :metrics
def initialize(metrics = ::Gitlab::Ci::Queue::Metrics)
@metrics = metrics
end
##
# Add a build to the pending builds queue
#
def queue_push!(build, metrics = ::Gitlab::Ci::Queue::Metrics)
in_transaction do
::Ci::PendingBuild.create!(build: build, project: project)
def push(build, transition)
raise InvalidQueueTransition unless transition.to == 'pending'
# TODO increment pending builds counter
transition.within_transaction do
::Ci::PendingBuild.create!(build: build, project: build.project)
end
# TODO increment pending builds counter
end
##
# Remove a build from the pending builds queue
#
def queue_pop!(build, metrics = ::Gitlab::Ci::Queue::Metrics)
in_transaction do
::Ci::PendingBuild.find(build.id).destroy!
def pop(build, transition)
raise InvalidQueueTransition unless transition.from == 'pending'
# TODO decrement pending builds counter
transition.within_transaction do
::Ci::PendingBuild.find_by(build_id: build.id)&.destroy! # rubocop:disable CodeReuse/ActiveRecord
end
# TODO decrement pending builds counter
end
##
# Unblock runner associated with given project / build
#
def execute(build, metrics = ::Gitlab::Ci::Queue::Metrics)
tick_for(build, build.project.all_runners, metrics)
def tick(build)
tick_for(build, build.project.all_runners)
end
private
def in_transaction
# TODO ensure that state machine transition transaction is open
#
yield
end
def tick_for(build, runners, metrics)
def tick_for(build, runners)
runners = runners.with_recent_runner_queue
runners = runners.with_tags if Feature.enabled?(:ci_preload_runner_tags, default_enabled: :yaml)
......
......@@ -14,7 +14,7 @@ class BuildQueueWorker # rubocop:disable Scalability/IdempotentWorker
# rubocop: disable CodeReuse/ActiveRecord
def perform(build_id)
Ci::Build.find_by(id: build_id).try do |build|
Ci::UpdateBuildQueueService.new.execute(build)
Ci::UpdateBuildQueueService.new.tick(build)
end
end
# rubocop: enable CodeReuse/ActiveRecord
......
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