Make scheduler cache generation number monotonic to avoid collision

This commit is contained in:
Bobby (Babak) Salamat 2018-04-27 13:23:25 -07:00
parent 625bce3ff6
commit b90892fa95
3 changed files with 39 additions and 7 deletions

View File

@ -992,6 +992,7 @@ func TestNodeOperators(t *testing.T) {
t.Errorf("Failed to find node %v in schedulercache.", node.Name)
}
expected.generation = got.generation
if !reflect.DeepEqual(got, expected) {
t.Errorf("Failed to add node into schedulercache:\n got: %+v \nexpected: %+v", got, expected)
}
@ -1003,6 +1004,7 @@ func TestNodeOperators(t *testing.T) {
if !found || len(cachedNodes) != 1 {
t.Errorf("failed to dump cached nodes:\n got: %v \nexpected: %v", cachedNodes, cache.nodes)
}
expected.generation = newNode.generation
if !reflect.DeepEqual(newNode, expected) {
t.Errorf("Failed to clone node:\n got: %+v, \n expected: %+v", newNode, expected)
}
@ -1010,12 +1012,15 @@ func TestNodeOperators(t *testing.T) {
// Case 3: update node attribute successfully.
node.Status.Allocatable[v1.ResourceMemory] = mem50m
expected.allocatableResource.Memory = mem50m.Value()
expected.generation++
cache.UpdateNode(nil, node)
got, found = cache.nodes[node.Name]
if !found {
t.Errorf("Failed to find node %v in schedulercache after UpdateNode.", node.Name)
}
if got.generation <= expected.generation {
t.Errorf("generation is not incremented. got: %v, expected: %v", got.generation, expected.generation)
}
expected.generation = got.generation
if !reflect.DeepEqual(got, expected) {
t.Errorf("Failed to update node in schedulercache:\n got: %+v \nexpected: %+v", got, expected)

View File

@ -20,6 +20,7 @@ import (
"errors"
"fmt"
"sync"
"sync/atomic"
"github.com/golang/glog"
@ -30,7 +31,10 @@ import (
"k8s.io/kubernetes/pkg/scheduler/util"
)
var emptyResource = Resource{}
var (
emptyResource = Resource{}
generation int64 = 0
)
// NodeInfo is node level aggregated information.
type NodeInfo struct {
@ -74,6 +78,11 @@ func initializeNodeTransientInfo() nodeTransientInfo {
return nodeTransientInfo{AllocatableVolumesCount: 0, RequestedVolumes: 0}
}
func incrementGeneration() int64 {
atomic.AddInt64(&generation, 1)
return generation
}
// nodeTransientInfo contains transient node information while scheduling.
type nodeTransientInfo struct {
// AllocatableVolumesCount contains number of volumes that could be attached to node.
@ -212,7 +221,7 @@ func NewNodeInfo(pods ...*v1.Pod) *NodeInfo {
nonzeroRequest: &Resource{},
allocatableResource: &Resource{},
TransientInfo: newTransientSchedulerInfo(),
generation: 0,
generation: incrementGeneration(),
usedPorts: make(util.HostPortInfo),
}
for _, pod := range pods {
@ -320,6 +329,7 @@ func (n *NodeInfo) AllocatableResource() Resource {
// SetAllocatableResource sets the allocatableResource information of given node.
func (n *NodeInfo) SetAllocatableResource(allocatableResource *Resource) {
n.allocatableResource = allocatableResource
n.generation = incrementGeneration()
}
// Clone returns a copy of this node.
@ -391,7 +401,7 @@ func (n *NodeInfo) AddPod(pod *v1.Pod) {
// Consume ports when pods added.
n.updateUsedPorts(pod, true)
n.generation++
n.generation = incrementGeneration()
}
// RemovePod subtracts pod information from this NodeInfo.
@ -442,7 +452,7 @@ func (n *NodeInfo) RemovePod(pod *v1.Pod) error {
// Release ports when remove Pods.
n.updateUsedPorts(pod, false)
n.generation++
n.generation = incrementGeneration()
return nil
}
@ -499,7 +509,7 @@ func (n *NodeInfo) SetNode(node *v1.Node) error {
}
}
n.TransientInfo = newTransientSchedulerInfo()
n.generation++
n.generation = incrementGeneration()
return nil
}
@ -515,7 +525,7 @@ func (n *NodeInfo) RemoveNode(node *v1.Node) error {
n.memoryPressureCondition = v1.ConditionUnknown
n.diskPressureCondition = v1.ConditionUnknown
n.pidPressureCondition = v1.ConditionUnknown
n.generation++
n.generation = incrementGeneration()
return nil
}

View File

@ -274,7 +274,12 @@ func TestNewNodeInfo(t *testing.T) {
},
}
gen := generation
ni := NewNodeInfo(pods...)
if ni.generation <= gen {
t.Errorf("generation is not incremented. previous: %v, current: %v", gen, ni.generation)
}
expected.generation = ni.generation
if !reflect.DeepEqual(expected, ni) {
t.Errorf("expected: %#v, got: %#v", expected, ni)
}
@ -584,10 +589,16 @@ func TestNodeInfoAddPod(t *testing.T) {
}
ni := fakeNodeInfo()
gen := ni.generation
for _, pod := range pods {
ni.AddPod(pod)
if ni.generation <= gen {
t.Errorf("generation is not incremented. Prev: %v, current: %v", gen, ni.generation)
}
gen = ni.generation
}
expected.generation = ni.generation
if !reflect.DeepEqual(expected, ni) {
t.Errorf("expected: %#v, got: %#v", expected, ni)
}
@ -788,6 +799,7 @@ func TestNodeInfoRemovePod(t *testing.T) {
for _, test := range tests {
ni := fakeNodeInfo(pods...)
gen := ni.generation
err := ni.RemovePod(test.pod)
if err != nil {
if test.errExpected {
@ -798,8 +810,13 @@ func TestNodeInfoRemovePod(t *testing.T) {
} else {
t.Errorf("expected no error, got: %v", err)
}
} else {
if ni.generation <= gen {
t.Errorf("generation is not incremented. Prev: %v, current: %v", gen, ni.generation)
}
}
test.expectedNodeInfo.generation = ni.generation
if !reflect.DeepEqual(test.expectedNodeInfo, ni) {
t.Errorf("expected: %#v, got: %#v", test.expectedNodeInfo, ni)
}