diff options
author | Kamil Trzciński <ayufan@ayufan.eu> | 2016-10-14 16:48:42 +0000 |
---|---|---|
committer | Kamil Trzciński <ayufan@ayufan.eu> | 2016-10-14 16:48:42 +0000 |
commit | 3f683038294887b25a87d075905cb4944c2ed595 (patch) | |
tree | a292bdd358a58276a63a9bf946af9bccf3711537 /app | |
parent | 9e199fe057a41cc1316cc96b4472c340895e98a9 (diff) | |
parent | 308769f82b19a142f443fb101a01a60c2b19757f (diff) | |
download | gitlab-ce-3f683038294887b25a87d075905cb4944c2ed595.tar.gz |
Merge branch 'feature/process-pipeline-hooks-asynchronously' into 'master'
Execute pipeline hooks asynchronously
## What does this MR do?
This MR makes it possible to execute pipeline hooks asynchronously, what should help to improve performance of CI pipeline processing.
## What are the relevant issue numbers?
Closes #23056
See merge request !6824
Diffstat (limited to 'app')
-rw-r--r-- | app/models/ci/build.rb | 22 | ||||
-rw-r--r-- | app/models/ci/pipeline.rb | 6 | ||||
-rw-r--r-- | app/services/create_deployment_service.rb | 34 | ||||
-rw-r--r-- | app/workers/build_coverage_worker.rb | 9 | ||||
-rw-r--r-- | app/workers/build_finished_worker.rb | 10 | ||||
-rw-r--r-- | app/workers/build_hooks_worker.rb | 9 | ||||
-rw-r--r-- | app/workers/build_success_worker.rb | 27 | ||||
-rw-r--r-- | app/workers/pipeline_hooks_worker.rb | 9 |
8 files changed, 100 insertions, 26 deletions
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 5dbf66173de..87475119b23 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -1,6 +1,7 @@ module Ci class Build < CommitStatus include TokenAuthenticatable + include AfterCommitQueue belongs_to :runner, class_name: 'Ci::Runner' belongs_to :trigger_request, class_name: 'Ci::TriggerRequest' @@ -75,25 +76,20 @@ module Ci state_machine :status do after_transition pending: :running do |build| - build.execute_hooks + build.run_after_commit do + BuildHooksWorker.perform_async(id) + end end after_transition any => [:success, :failed, :canceled] do |build| - build.update_coverage - build.execute_hooks + build.run_after_commit do + BuildFinishedWorker.perform_async(id) + end end after_transition any => [:success] do |build| - if build.environment.present? - service = CreateDeploymentService.new( - build.project, build.user, - environment: build.environment, - sha: build.sha, - ref: build.ref, - tag: build.tag, - options: build.options.to_h[:environment], - variables: build.variables) - service.execute(build) + build.run_after_commit do + BuildSuccessWorker.perform_async(id) end end end diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 957f6755b2e..4fdb5fef4fb 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -76,7 +76,11 @@ module Ci end after_transition do |pipeline, transition| - pipeline.execute_hooks unless transition.loopback? + next if transition.loopback? + + pipeline.run_after_commit do + PipelineHooksWorker.perform_async(id) + end end end diff --git a/app/services/create_deployment_service.rb b/app/services/create_deployment_service.rb index 799ad3e1bd0..ff9a8310a8c 100644 --- a/app/services/create_deployment_service.rb +++ b/app/services/create_deployment_service.rb @@ -2,25 +2,35 @@ require_relative 'base_service' class CreateDeploymentService < BaseService def execute(deployable = nil) - environment = find_or_create_environment + return unless executable? - deployment = project.deployments.create( - environment: environment, + ActiveRecord::Base.transaction do + @deployable = deployable + @environment = prepare_environment + + deploy.tap do |deployment| + deployment.update_merge_request_metrics! + end + end + end + + private + + def executable? + project && name.present? + end + + def deploy + project.deployments.create( + environment: @environment, ref: params[:ref], tag: params[:tag], sha: params[:sha], user: current_user, - deployable: deployable - ) - - deployment.update_merge_request_metrics! - - deployment + deployable: @deployable) end - private - - def find_or_create_environment + def prepare_environment project.environments.find_or_create_by(name: expanded_name) do |environment| environment.external_url = expanded_url end diff --git a/app/workers/build_coverage_worker.rb b/app/workers/build_coverage_worker.rb new file mode 100644 index 00000000000..0680645a8db --- /dev/null +++ b/app/workers/build_coverage_worker.rb @@ -0,0 +1,9 @@ +class BuildCoverageWorker + include Sidekiq::Worker + sidekiq_options queue: :default + + def perform(build_id) + Ci::Build.find_by(id: build_id) + .try(:update_coverage) + end +end diff --git a/app/workers/build_finished_worker.rb b/app/workers/build_finished_worker.rb new file mode 100644 index 00000000000..e7286b77ac5 --- /dev/null +++ b/app/workers/build_finished_worker.rb @@ -0,0 +1,10 @@ +class BuildFinishedWorker + include Sidekiq::Worker + + def perform(build_id) + Ci::Build.find_by(id: build_id).try do |build| + BuildCoverageWorker.new.perform(build.id) + BuildHooksWorker.new.perform(build.id) + end + end +end diff --git a/app/workers/build_hooks_worker.rb b/app/workers/build_hooks_worker.rb new file mode 100644 index 00000000000..e22ececb3fd --- /dev/null +++ b/app/workers/build_hooks_worker.rb @@ -0,0 +1,9 @@ +class BuildHooksWorker + include Sidekiq::Worker + sidekiq_options queue: :default + + def perform(build_id) + Ci::Build.find_by(id: build_id) + .try(:execute_hooks) + end +end diff --git a/app/workers/build_success_worker.rb b/app/workers/build_success_worker.rb new file mode 100644 index 00000000000..500d357ce31 --- /dev/null +++ b/app/workers/build_success_worker.rb @@ -0,0 +1,27 @@ +class BuildSuccessWorker + include Sidekiq::Worker + sidekiq_options queue: :default + + def perform(build_id) + Ci::Build.find_by(id: build_id).try do |build| + create_deployment(build) + end + end + + private + + def create_deployment(build) + return if build.environment.blank? + + service = CreateDeploymentService.new( + build.project, build.user, + environment: build.environment, + sha: build.sha, + ref: build.ref, + tag: build.tag, + options: build.options.to_h[:environment], + variables: build.variables) + + service.execute(build) + end +end diff --git a/app/workers/pipeline_hooks_worker.rb b/app/workers/pipeline_hooks_worker.rb new file mode 100644 index 00000000000..ab5e9f6daad --- /dev/null +++ b/app/workers/pipeline_hooks_worker.rb @@ -0,0 +1,9 @@ +class PipelineHooksWorker + include Sidekiq::Worker + sidekiq_options queue: :default + + def perform(pipeline_id) + Ci::Pipeline.find_by(id: pipeline_id) + .try(:execute_hooks) + end +end |