Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Jérome Perrin
gitlab-ce
Commits
ee2e5835
Commit
ee2e5835
authored
Jun 13, 2016
by
Kamil Trzcinski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fair usage of Shared Runners
parent
6aefd3c3
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
60 additions
and
6 deletions
+60
-6
CHANGELOG
CHANGELOG
+1
-0
app/services/ci/register_build_service.rb
app/services/ci/register_build_service.rb
+19
-6
spec/services/ci/register_build_service_spec.rb
spec/services/ci/register_build_service_spec.rb
+40
-0
No files found.
CHANGELOG
View file @
ee2e5835
...
...
@@ -19,6 +19,7 @@ v 8.9.0 (unreleased)
- Added descriptions to notification settings dropdown
- Improve note validation to prevent errors when creating invalid note via API
- Reduce number of fog gem dependencies
- Implement a fair usage of shared runners
- Remove project notification settings associated with deleted projects
- Fix 404 page when viewing TODOs that contain milestones or labels in different projects
- Redesign navigation for project pages
...
...
app/services/ci/register_build_service.rb
View file @
ee2e5835
...
...
@@ -7,15 +7,15 @@ module Ci
builds
=
if
current_runner
.
shared?
# don't run projects which have not enables shared runners
builds
.
joins
(
:project
).
where
(
projects:
{
builds_enabled:
true
,
shared_runners_enabled:
true
})
# this returns builds that are ordered by number of running builds
# we prefer projects that don't use shared runners at all
builds
.
joins
(
"JOIN (
#{
projects_with_builds_for_shared_runners
.
to_sql
}
) AS projects ON ci_builds.gl_project_id=projects.gl_project_id"
).
order
(
'projects.running_builds ASC'
,
'ci_builds.id ASC'
)
else
# do run projects which are only assigned to this runner
builds
.
where
(
project:
current_runner
.
projects
.
where
(
builds_enabled:
true
))
# do run projects which are only assigned to this runner
(FIFO)
builds
.
where
(
project:
current_runner
.
projects
.
where
(
builds_enabled:
true
))
.
order
(
'created_at ASC'
)
end
builds
=
builds
.
order
(
'created_at ASC'
)
build
=
builds
.
find
do
|
build
|
build
.
can_be_served?
(
current_runner
)
end
...
...
@@ -35,5 +35,18 @@ module Ci
rescue
StateMachines
::
InvalidTransition
nil
end
private
def
projects_with_builds_for_shared_runners
Ci
::
Build
.
running_or_pending
.
joins
(
:project
).
where
(
projects:
{
builds_enabled:
true
,
shared_runners_enabled:
true
}).
group
(
:gl_project_id
).
select
(
:gl_project_id
,
"count(case when status = 'running' AND runner_id = (
#{
shared_runners
.
to_sql
}
) then 1 end) as running_builds"
)
end
def
shared_runners
Ci
::
Runner
.
shared
.
select
(
:id
)
end
end
end
spec/services/ci/register_build_service_spec.rb
View file @
ee2e5835
...
...
@@ -50,6 +50,46 @@ module Ci
project
.
update
(
shared_runners_enabled:
true
)
end
context
'for multiple builds'
do
let!
(
:project2
)
{
create
:empty_project
,
shared_runners_enabled:
true
}
let!
(
:pipeline2
)
{
create
:ci_pipeline
,
project:
project2
}
let!
(
:project3
)
{
create
:empty_project
,
shared_runners_enabled:
true
}
let!
(
:pipeline3
)
{
create
:ci_pipeline
,
project:
project3
}
let!
(
:build1_project1
)
{
pending_build
}
let!
(
:build2_project1
)
{
FactoryGirl
.
create
:ci_build
,
pipeline:
pipeline
}
let!
(
:build3_project1
)
{
FactoryGirl
.
create
:ci_build
,
pipeline:
pipeline
}
let!
(
:build1_project2
)
{
FactoryGirl
.
create
:ci_build
,
pipeline:
pipeline2
}
let!
(
:build2_project2
)
{
FactoryGirl
.
create
:ci_build
,
pipeline:
pipeline2
}
let!
(
:build1_project3
)
{
FactoryGirl
.
create
:ci_build
,
pipeline:
pipeline3
}
it
'prefers projects without builds first'
do
# it gets for one build from each of the projects
expect
(
service
.
execute
(
shared_runner
)).
to
eq
(
build1_project1
)
expect
(
service
.
execute
(
shared_runner
)).
to
eq
(
build1_project2
)
expect
(
service
.
execute
(
shared_runner
)).
to
eq
(
build1_project3
)
# then it gets a second build from each of the projects
expect
(
service
.
execute
(
shared_runner
)).
to
eq
(
build2_project1
)
expect
(
service
.
execute
(
shared_runner
)).
to
eq
(
build2_project2
)
# in the end the third build
expect
(
service
.
execute
(
shared_runner
)).
to
eq
(
build3_project1
)
end
it
'equalises number of running builds'
do
# after finishing the first build for project 1, get a second build from the same project
expect
(
service
.
execute
(
shared_runner
)).
to
eq
(
build1_project1
)
build1_project1
.
success
expect
(
service
.
execute
(
shared_runner
)).
to
eq
(
build2_project1
)
expect
(
service
.
execute
(
shared_runner
)).
to
eq
(
build1_project2
)
build1_project2
.
success
expect
(
service
.
execute
(
shared_runner
)).
to
eq
(
build2_project2
)
expect
(
service
.
execute
(
shared_runner
)).
to
eq
(
build1_project3
)
expect
(
service
.
execute
(
shared_runner
)).
to
eq
(
build3_project1
)
end
end
context
'shared runner'
do
let
(
:build
)
{
service
.
execute
(
shared_runner
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment