Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
abd0d7b2
Commit
abd0d7b2
authored
May 15, 2015
by
Prashanth B
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #8261 from lavalamp/scheduler
Make scheduler optimistic about its bindings
parents
6144b491
3a7086fd
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
31 additions
and
15 deletions
+31
-15
scheduler.go
plugin/pkg/scheduler/scheduler.go
+23
-12
scheduler_test.go
plugin/pkg/scheduler/scheduler_test.go
+8
-3
No files found.
plugin/pkg/scheduler/scheduler.go
View file @
abd0d7b2
...
@@ -104,20 +104,21 @@ func (s *Scheduler) Run() {
...
@@ -104,20 +104,21 @@ func (s *Scheduler) Run() {
go
util
.
Until
(
s
.
scheduleOne
,
0
,
s
.
config
.
StopEverything
)
go
util
.
Until
(
s
.
scheduleOne
,
0
,
s
.
config
.
StopEverything
)
}
}
func
(
s
*
Scheduler
)
schedule
One
(
)
{
func
(
s
*
Scheduler
)
schedule
()
(
executeBinding
func
()
)
{
pod
:=
s
.
config
.
NextPod
()
pod
:=
s
.
config
.
NextPod
()
glog
.
V
(
3
)
.
Infof
(
"Attempting to schedule: %v"
,
pod
)
glog
.
V
(
3
)
.
Infof
(
"Attempting to schedule: %v"
,
pod
)
start
:=
time
.
Now
()
start
:=
time
.
Now
()
defer
func
()
{
recordTime
:=
func
()
{
metrics
.
E2eSchedulingLatency
.
Observe
(
metrics
.
SinceInMicroseconds
(
start
))
metrics
.
E2eSchedulingLatency
.
Observe
(
metrics
.
SinceInMicroseconds
(
start
))
}
()
}
dest
,
err
:=
s
.
config
.
Algorithm
.
Schedule
(
pod
,
s
.
config
.
MinionLister
)
dest
,
err
:=
s
.
config
.
Algorithm
.
Schedule
(
pod
,
s
.
config
.
MinionLister
)
metrics
.
SchedulingAlgorithmLatency
.
Observe
(
metrics
.
SinceInMicroseconds
(
start
))
metrics
.
SchedulingAlgorithmLatency
.
Observe
(
metrics
.
SinceInMicroseconds
(
start
))
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
V
(
1
)
.
Infof
(
"Failed to schedule: %v"
,
pod
)
glog
.
V
(
1
)
.
Infof
(
"Failed to schedule: %v"
,
pod
)
s
.
config
.
Recorder
.
Eventf
(
pod
,
"failedScheduling"
,
"Error scheduling: %v"
,
err
)
s
.
config
.
Recorder
.
Eventf
(
pod
,
"failedScheduling"
,
"Error scheduling: %v"
,
err
)
s
.
config
.
Error
(
pod
,
err
)
s
.
config
.
Error
(
pod
,
err
)
return
recordTime
()
return
func
()
{}
}
}
b
:=
&
api
.
Binding
{
b
:=
&
api
.
Binding
{
ObjectMeta
:
api
.
ObjectMeta
{
Namespace
:
pod
.
Namespace
,
Name
:
pod
.
Name
},
ObjectMeta
:
api
.
ObjectMeta
{
Namespace
:
pod
.
Namespace
,
Name
:
pod
.
Name
},
...
@@ -127,22 +128,32 @@ func (s *Scheduler) scheduleOne() {
...
@@ -127,22 +128,32 @@ func (s *Scheduler) scheduleOne() {
},
},
}
}
// We want to add the pod to the model iff the bind succeeds, but we don't want to race
// Actually do the binding asynchronously with respect to the scheduling queue.
// with any deletions, which happen asyncronously.
return
func
()
{
s
.
config
.
Modeler
.
LockedAction
(
func
()
{
defer
recordTime
()
defer
util
.
HandleCrash
()
// Make an object representing our assumtion that the bind will succeed.
assumed
:=
*
pod
assumed
.
Spec
.
Host
=
dest
s
.
config
.
Modeler
.
AssumePod
(
&
assumed
)
bindingStart
:=
time
.
Now
()
bindingStart
:=
time
.
Now
()
err
:=
s
.
config
.
Binder
.
Bind
(
b
)
err
:=
s
.
config
.
Binder
.
Bind
(
b
)
metrics
.
BindingLatency
.
Observe
(
metrics
.
SinceInMicroseconds
(
bindingStart
))
metrics
.
BindingLatency
.
Observe
(
metrics
.
SinceInMicroseconds
(
bindingStart
))
if
err
!=
nil
{
if
err
!=
nil
{
// Remove our (now invalid) assumption
s
.
config
.
Modeler
.
ForgetPod
(
&
assumed
)
glog
.
V
(
1
)
.
Infof
(
"Failed to bind pod: %v"
,
err
)
glog
.
V
(
1
)
.
Infof
(
"Failed to bind pod: %v"
,
err
)
s
.
config
.
Recorder
.
Eventf
(
pod
,
"failedScheduling"
,
"Binding rejected: %v"
,
err
)
s
.
config
.
Recorder
.
Eventf
(
pod
,
"failedScheduling"
,
"Binding rejected: %v"
,
err
)
s
.
config
.
Error
(
pod
,
err
)
s
.
config
.
Error
(
pod
,
err
)
return
return
}
}
s
.
config
.
Recorder
.
Eventf
(
pod
,
"scheduled"
,
"Successfully assigned %v to %v"
,
pod
.
Name
,
dest
)
s
.
config
.
Recorder
.
Eventf
(
pod
,
"scheduled"
,
"Successfully assigned %v to %v"
,
pod
.
Name
,
dest
)
// tell the model to assume that this binding took effect.
}
assumed
:=
*
pod
}
assumed
.
Spec
.
Host
=
dest
s
.
config
.
Modeler
.
AssumePod
(
&
assumed
)
func
(
s
*
Scheduler
)
scheduleOne
()
{
})
bind
:=
s
.
schedule
()
go
bind
()
}
}
plugin/pkg/scheduler/scheduler_test.go
View file @
abd0d7b2
...
@@ -113,6 +113,11 @@ func TestScheduler(t *testing.T) {
...
@@ -113,6 +113,11 @@ func TestScheduler(t *testing.T) {
AssumePodFunc
:
func
(
pod
*
api
.
Pod
)
{
AssumePodFunc
:
func
(
pod
*
api
.
Pod
)
{
gotAssumedPod
=
pod
gotAssumedPod
=
pod
},
},
ForgetPodFunc
:
func
(
pod
*
api
.
Pod
)
{
if
gotAssumedPod
!=
nil
&&
gotAssumedPod
.
Name
==
pod
.
Name
&&
gotAssumedPod
.
Namespace
==
pod
.
Namespace
{
gotAssumedPod
=
nil
}
},
},
},
MinionLister
:
algorithm
.
FakeMinionLister
(
MinionLister
:
algorithm
.
FakeMinionLister
(
api
.
NodeList
{
Items
:
[]
api
.
Node
{{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"machine1"
}}}},
api
.
NodeList
{
Items
:
[]
api
.
Node
{{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"machine1"
}}}},
...
@@ -139,7 +144,7 @@ func TestScheduler(t *testing.T) {
...
@@ -139,7 +144,7 @@ func TestScheduler(t *testing.T) {
}
}
close
(
called
)
close
(
called
)
})
})
s
.
schedule
One
()
s
.
schedule
()
()
if
e
,
a
:=
item
.
expectAssumedPod
,
gotAssumedPod
;
!
reflect
.
DeepEqual
(
e
,
a
)
{
if
e
,
a
:=
item
.
expectAssumedPod
,
gotAssumedPod
;
!
reflect
.
DeepEqual
(
e
,
a
)
{
t
.
Errorf
(
"%v: assumed pod: wanted %v, got %v"
,
i
,
e
,
a
)
t
.
Errorf
(
"%v: assumed pod: wanted %v, got %v"
,
i
,
e
,
a
)
}
}
...
@@ -229,7 +234,7 @@ func TestSchedulerForgetAssumedPodAfterDelete(t *testing.T) {
...
@@ -229,7 +234,7 @@ func TestSchedulerForgetAssumedPodAfterDelete(t *testing.T) {
// scheduledPodStore: []
// scheduledPodStore: []
// assumedPods: []
// assumedPods: []
s
.
schedule
One
()
s
.
schedule
()
()
// queuedPodStore: []
// queuedPodStore: []
// scheduledPodStore: [foo:8080]
// scheduledPodStore: [foo:8080]
// assumedPods: [foo:8080]
// assumedPods: [foo:8080]
...
@@ -283,7 +288,7 @@ func TestSchedulerForgetAssumedPodAfterDelete(t *testing.T) {
...
@@ -283,7 +288,7 @@ func TestSchedulerForgetAssumedPodAfterDelete(t *testing.T) {
close
(
called
)
close
(
called
)
})
})
s
.
schedule
One
()
s
.
schedule
()
()
expectBind
=
&
api
.
Binding
{
expectBind
=
&
api
.
Binding
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"bar"
},
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"bar"
},
...
...
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