Skip to content

Commit 1b9e35b

Browse files
committed
allow configuring a per-repo concurrency limit via config
1 parent 73d0f04 commit 1b9e35b

File tree

5 files changed

+74
-11
lines changed

5 files changed

+74
-11
lines changed

lib/travis/scheduler/config.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class Config < Travis::Config
1010
enterprise: false,
1111
github: { api_url: 'https://api.github.com', source_host: 'github.com' },
1212
interval: 2,
13-
limit: { default: 5, by_owner: {}, delegate: {} },
13+
limit: { default: 5, by_owner: {}, by_repo: {}, delegate: {} },
1414
lock: { strategy: :redis, ttl: 150 },
1515
logger: { time_format: false, process_id: false, thread_id: false },
1616
log_level: :info,

lib/travis/scheduler/limit/by_repo.rb

+19-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@ class ByRepo < Struct.new(:context, :owners, :job, :selected, :state, :config)
88
include Helper::Context
99

1010
def enqueue?
11-
unlimited? || by_settings
11+
# return false unless by_config
12+
# return false if max_by_setting && !by_setting
13+
# p [max_by_setting, by_setting]
14+
# unlimited? || by_setting
15+
return false if limited_by_config?
16+
return false if limited_by_setting?
17+
true
1218
end
1319

1420
def reports
@@ -17,24 +23,30 @@ def reports
1723

1824
private
1925

20-
def unlimited?
21-
max == 0
26+
def limited_by_config?
27+
result = max_by_config > 0 && current >= max_by_config
28+
report :repo_config, max_by_config if result
29+
result
2230
end
2331

24-
def by_settings
25-
result = current < max
26-
report :repo_settings, max unless result
32+
def limited_by_setting?
33+
result = max_by_setting > 0 && current >= max_by_setting
34+
report :repo_settings, max_by_setting if result
2735
result
2836
end
2937

3038
def current
3139
state.running_by_repo(repo.id) + selected.select { |j| j.repository_id == repo.id }.size
3240
end
3341

34-
def max
42+
def max_by_setting
3543
repo.settings.maximum_number_of_builds.to_i
3644
end
3745

46+
def max_by_config
47+
config[:limit][:by_repo][repo.slug].to_i
48+
end
49+
3850
def repo
3951
job.repository
4052
end

lib/travis/scheduler/limit/by_stage.rb

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ class ByStage < Struct.new(:context, :owners, :job, :queued, :state, :config)
1010
def enqueue?
1111
return true unless job.stage_number
1212
!!report if queueable?
13+
# return true unless job.stage_number
14+
# throw :result, :limited unless queueable?
15+
# report
16+
# true
1317
end
1418

1519
def reports

lib/travis/scheduler/limit/jobs.rb

+6-3
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,14 @@ def check(job)
7373
end
7474

7575
def enqueue?(job)
76-
limits_for(job).map do |limit|
77-
result = limit.enqueue?
76+
a = limits_for(job).map do |limit|
77+
result = catch(:result) { limit.enqueue? }
7878
report *limit.reports
79+
throw :result, result if result == :limited
7980
result
80-
end.inject(&:&)
81+
end
82+
# p a
83+
a.inject(&:&)
8184
end
8285

8386
def limits_for(job)

spec/travis/scheduler/limit_spec.rb

+44
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,18 @@ def create_jobs(count, attrs = {})
9191
it { expect(report).to include('user svenfuchs: total: 3, running: 0, queueable: 1') }
9292
end
9393

94+
describe 'with a default limit 5 and a repo keychain/config limit 2' do
95+
before { config.limit.default = 5 }
96+
before { config.limit.by_repo = { repo.slug => 2 } }
97+
before { create_jobs(3) }
98+
before { repo.settings.update_attributes!(maximum_number_of_builds: 2) }
99+
before { subject }
100+
101+
it { expect(subject.size).to eq 2 }
102+
it { expect(report).to include('max jobs for repo svenfuchs/gem-release by repo_config: 2') }
103+
it { expect(report).to include('user svenfuchs: total: 3, running: 0, queueable: 2') }
104+
end
105+
94106
describe 'with a default limit 5 and a repo settings limit 2' do
95107
before { config.limit.default = 5 }
96108
before { create_jobs(3) }
@@ -193,4 +205,36 @@ def create_jobs(count, attrs = {})
193205
it { expect(subject.size).to eq 2 }
194206
it { expect(report).to include("jobs for build #{build.id} limited at stage: 1 (queueable: 2)") }
195207
end
208+
209+
describe 'stages with a a repo config limit 1' do
210+
let(:one) { FactoryGirl.create(:stage, number: 1) }
211+
let(:two) { FactoryGirl.create(:stage, number: 2) }
212+
213+
before { create_jobs(1, owner: owner, state: :created, stage: one, stage_number: '1.1') }
214+
before { create_jobs(1, owner: owner, state: :created, stage: one, stage_number: '1.2') }
215+
before { create_jobs(1, owner: owner, state: :created, stage: two, stage_number: '2.1') }
216+
before { config.limit.default = 5 }
217+
before { config.limit.by_repo = { repo.slug => 1 } }
218+
before { subject }
219+
220+
it { expect(subject.size).to eq 1 }
221+
it { expect(report).to include("jobs for build #{build.id} limited at stage: 1 (queueable: 2)") }
222+
it { expect(report).to include('max jobs for repo svenfuchs/gem-release by repo_config: 1') }
223+
end
224+
225+
describe 'stages with a a repo settings limit 5' do
226+
let(:one) { FactoryGirl.create(:stage, number: 1) }
227+
let(:two) { FactoryGirl.create(:stage, number: 2) }
228+
229+
before { create_jobs(1, owner: owner, state: :created, stage: one, stage_number: '1.1') }
230+
before { create_jobs(1, owner: owner, state: :created, stage: one, stage_number: '1.2') }
231+
before { create_jobs(1, owner: owner, state: :created, stage: two, stage_number: '2.1') }
232+
before { config.limit.default = 5 }
233+
before { repo.settings.update_attributes!(maximum_number_of_builds: 1) }
234+
before { subject }
235+
236+
it { expect(subject.size).to eq 1 }
237+
it { expect(report).to include("jobs for build #{build.id} limited at stage: 1 (queueable: 2)") }
238+
it { expect(report).to include('max jobs for repo svenfuchs/gem-release by repo_settings: 1') }
239+
end
196240
end

0 commit comments

Comments
 (0)