diff options
-rw-r--r-- | app/models/ci/build.rb | 2 | ||||
-rw-r--r-- | app/services/ci/register_job_service.rb | 5 | ||||
-rw-r--r-- | changelogs/unreleased/1340-request-job-with-age.yml | 5 | ||||
-rw-r--r-- | db/migrate/20190516011213_add_build_queued_at_index.rb | 19 | ||||
-rw-r--r-- | db/schema.rb | 3 | ||||
-rw-r--r-- | lib/api/runner.rb | 1 | ||||
-rw-r--r-- | spec/requests/api/runner_spec.rb | 24 |
7 files changed, 58 insertions, 1 deletions
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 0a90995f689..1b67a7272bc 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -140,6 +140,8 @@ module Ci where("EXISTS (?)", matcher) end + scope :queued_before, ->(time) { where(arel_table[:queued_at].lt(time)) } + ## # TODO: Remove these mounters when we remove :ci_enable_legacy_artifacts feature flag mount_uploader :legacy_artifacts_file, LegacyArtifactUploader, mount_on: :artifacts_file diff --git a/app/services/ci/register_job_service.rb b/app/services/ci/register_job_service.rb index 6707a1363d0..baa3f898b2d 100644 --- a/app/services/ci/register_job_service.rb +++ b/app/services/ci/register_job_service.rb @@ -36,6 +36,11 @@ module Ci builds = builds.with_any_tags end + # pick builds that older than specified age + if params.key?(:job_age) + builds = builds.queued_before(params[:job_age].seconds.ago) + end + builds.each do |build| next unless runner.can_pick?(build) diff --git a/changelogs/unreleased/1340-request-job-with-age.yml b/changelogs/unreleased/1340-request-job-with-age.yml new file mode 100644 index 00000000000..766ac008c2e --- /dev/null +++ b/changelogs/unreleased/1340-request-job-with-age.yml @@ -0,0 +1,5 @@ +--- +title: "Added option to filter jobs by age in the /job/request API endpoint." +merge_request: 1340 +author: Dmitry Chepurovskiy +type: added diff --git a/db/migrate/20190516011213_add_build_queued_at_index.rb b/db/migrate/20190516011213_add_build_queued_at_index.rb new file mode 100644 index 00000000000..77ffa7cd4e9 --- /dev/null +++ b/db/migrate/20190516011213_add_build_queued_at_index.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +# This migration make queued_at field indexed to speed up builds filtering by job_age + +class AddBuildQueuedAtIndex < ActiveRecord::Migration[5.1] + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def up + add_concurrent_index :ci_builds, :queued_at + end + + def down + remove_concurrent_index :ci_builds, :queued_at + end +end diff --git a/db/schema.rb b/db/schema.rb index 9d367938cec..412b5313b69 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20190515125613) do +ActiveRecord::Schema.define(version: 20190516011213) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -380,6 +380,7 @@ ActiveRecord::Schema.define(version: 20190515125613) do t.index ["project_id", "id"], name: "index_ci_builds_on_project_id_and_id", using: :btree t.index ["project_id", "status"], name: "index_ci_builds_project_id_and_status_for_live_jobs_partial2", where: "(((type)::text = 'Ci::Build'::text) AND ((status)::text = ANY (ARRAY[('running'::character varying)::text, ('pending'::character varying)::text, ('created'::character varying)::text])))", using: :btree t.index ["protected"], name: "index_ci_builds_on_protected", using: :btree + t.index ["queued_at"], name: "index_ci_builds_on_queued_at", using: :btree t.index ["runner_id"], name: "index_ci_builds_on_runner_id", using: :btree t.index ["scheduled_at"], name: "partial_index_ci_builds_on_scheduled_at_with_scheduled_jobs", where: "((scheduled_at IS NOT NULL) AND ((type)::text = 'Ci::Build'::text) AND ((status)::text = 'scheduled'::text))", using: :btree t.index ["stage_id", "stage_idx"], name: "tmp_build_stage_position_index", where: "(stage_idx IS NOT NULL)", using: :btree diff --git a/lib/api/runner.rb b/lib/api/runner.rb index ea36c24eca2..fdf4904e9f5 100644 --- a/lib/api/runner.rb +++ b/lib/api/runner.rb @@ -98,6 +98,7 @@ module API optional :certificate, type: String, desc: %q(Session's certificate) optional :authorization, type: String, desc: %q(Session's authorization) end + optional :job_age, type: Integer, desc: %q(Job should be older than passed age in seconds to be ran on runner) end post '/request' do authenticate_runner! diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb index b331da1acba..4006e697a41 100644 --- a/spec/requests/api/runner_spec.rb +++ b/spec/requests/api/runner_spec.rb @@ -542,6 +542,30 @@ describe API::Runner, :clean_gitlab_redis_shared_state do end end + context 'when job filtered by job_age' do + let!(:job) { create(:ci_build, :tag, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0, queued_at: 60.seconds.ago) } + + context 'job is queued less than job_age parameter' do + let(:job_age) { 120 } + + it 'gives 204' do + request_job(job_age: job_age) + + expect(response).to have_gitlab_http_status(204) + end + end + + context 'job is queued more than job_age parameter' do + let(:job_age) { 30 } + + it 'picks a job' do + request_job(job_age: job_age) + + expect(response).to have_gitlab_http_status(201) + end + end + end + context 'when job is made for branch' do it 'sets tag as ref_type' do request_job |