mirror of https://github.com/k3s-io/k3s
Clean up names in equivalence package.
Remove stutter from names and provide more idiomatic patterns. This makes call sites that use equivalence cache easier to read.pull/8/head
parent
31c746d960
commit
b571065bc4
|
@ -31,19 +31,51 @@ import (
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EquivalenceCache saves and reuses the output of predicate functions. Use
|
// Cache saves and reuses the output of predicate functions. Use RunPredicate to
|
||||||
// RunPredicate to get or update the cached results. An appropriate Invalidate*
|
// get or update the cached results. An appropriate Invalidate* function should
|
||||||
// function should be called when some predicate results are no longer valid.
|
// be called when some predicate results are no longer valid.
|
||||||
//
|
//
|
||||||
// Internally, results are keyed by node name, predicate name, and "equivalence
|
// Internally, results are keyed by node name, predicate name, and "equivalence
|
||||||
// class". (Equivalence class is defined in the `EquivalenceClassInfo` type.)
|
// class". (Equivalence class is defined in the `Class` type.) Saved results
|
||||||
// Saved results will be reused until an appropriate invalidation function is
|
// will be reused until an appropriate invalidation function is called.
|
||||||
// called.
|
type Cache struct {
|
||||||
type EquivalenceCache struct {
|
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
cache nodeMap
|
cache nodeMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewCache returns an empty Cache.
|
||||||
|
func NewCache() *Cache {
|
||||||
|
return &Cache{
|
||||||
|
cache: make(nodeMap),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Class represents a set of pods which are equivalent from the perspective of
|
||||||
|
// the scheduler. i.e. the scheduler would make the same decision for any pod
|
||||||
|
// from the same class.
|
||||||
|
type Class struct {
|
||||||
|
// Equivalence hash
|
||||||
|
hash uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClass returns the equivalence class for a given Pod. The returned Class
|
||||||
|
// objects will be equal for two Pods in the same class. nil values should not
|
||||||
|
// be considered equal to each other.
|
||||||
|
//
|
||||||
|
// NOTE: Make sure to compare types of Class and not *Class.
|
||||||
|
// TODO(misterikkit): Return error instead of nil *Class.
|
||||||
|
func NewClass(pod *v1.Pod) *Class {
|
||||||
|
equivalencePod := getEquivalencePod(pod)
|
||||||
|
if equivalencePod != nil {
|
||||||
|
hash := fnv.New32a()
|
||||||
|
hashutil.DeepHashObject(hash, equivalencePod)
|
||||||
|
return &Class{
|
||||||
|
hash: uint64(hash.Sum32()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// nodeMap stores PredicateCaches with node name as the key.
|
// nodeMap stores PredicateCaches with node name as the key.
|
||||||
type nodeMap map[string]predicateMap
|
type nodeMap map[string]predicateMap
|
||||||
|
|
||||||
|
@ -59,25 +91,17 @@ type predicateResult struct {
|
||||||
FailReasons []algorithm.PredicateFailureReason
|
FailReasons []algorithm.PredicateFailureReason
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEquivalenceCache returns EquivalenceCache to speed up predicates by caching
|
|
||||||
// result from previous scheduling.
|
|
||||||
func NewEquivalenceCache() *EquivalenceCache {
|
|
||||||
return &EquivalenceCache{
|
|
||||||
cache: make(nodeMap),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunPredicate returns a cached predicate result. In case of a cache miss, the predicate will be
|
// RunPredicate returns a cached predicate result. In case of a cache miss, the predicate will be
|
||||||
// run and its results cached for the next call.
|
// run and its results cached for the next call.
|
||||||
//
|
//
|
||||||
// NOTE: RunPredicate will not update the equivalence cache if the given NodeInfo is stale.
|
// NOTE: RunPredicate will not update the equivalence cache if the given NodeInfo is stale.
|
||||||
func (ec *EquivalenceCache) RunPredicate(
|
func (c *Cache) RunPredicate(
|
||||||
pred algorithm.FitPredicate,
|
pred algorithm.FitPredicate,
|
||||||
predicateKey string,
|
predicateKey string,
|
||||||
pod *v1.Pod,
|
pod *v1.Pod,
|
||||||
meta algorithm.PredicateMetadata,
|
meta algorithm.PredicateMetadata,
|
||||||
nodeInfo *schedulercache.NodeInfo,
|
nodeInfo *schedulercache.NodeInfo,
|
||||||
equivClassInfo *EquivalenceClassInfo,
|
equivClass *Class,
|
||||||
cache schedulercache.Cache,
|
cache schedulercache.Cache,
|
||||||
) (bool, []algorithm.PredicateFailureReason, error) {
|
) (bool, []algorithm.PredicateFailureReason, error) {
|
||||||
if nodeInfo == nil || nodeInfo.Node() == nil {
|
if nodeInfo == nil || nodeInfo.Node() == nil {
|
||||||
|
@ -85,7 +109,7 @@ func (ec *EquivalenceCache) RunPredicate(
|
||||||
return false, []algorithm.PredicateFailureReason{}, fmt.Errorf("nodeInfo is nil or node is invalid")
|
return false, []algorithm.PredicateFailureReason{}, fmt.Errorf("nodeInfo is nil or node is invalid")
|
||||||
}
|
}
|
||||||
|
|
||||||
result, ok := ec.lookupResult(pod.GetName(), nodeInfo.Node().GetName(), predicateKey, equivClassInfo.hash)
|
result, ok := c.lookupResult(pod.GetName(), nodeInfo.Node().GetName(), predicateKey, equivClass.hash)
|
||||||
if ok {
|
if ok {
|
||||||
return result.Fit, result.FailReasons, nil
|
return result.Fit, result.FailReasons, nil
|
||||||
}
|
}
|
||||||
|
@ -94,13 +118,13 @@ func (ec *EquivalenceCache) RunPredicate(
|
||||||
return fit, reasons, err
|
return fit, reasons, err
|
||||||
}
|
}
|
||||||
if cache != nil {
|
if cache != nil {
|
||||||
ec.updateResult(pod.GetName(), predicateKey, fit, reasons, equivClassInfo.hash, cache, nodeInfo)
|
c.updateResult(pod.GetName(), predicateKey, fit, reasons, equivClass.hash, cache, nodeInfo)
|
||||||
}
|
}
|
||||||
return fit, reasons, nil
|
return fit, reasons, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateResult updates the cached result of a predicate.
|
// updateResult updates the cached result of a predicate.
|
||||||
func (ec *EquivalenceCache) updateResult(
|
func (c *Cache) updateResult(
|
||||||
podName, predicateKey string,
|
podName, predicateKey string,
|
||||||
fit bool,
|
fit bool,
|
||||||
reasons []algorithm.PredicateFailureReason,
|
reasons []algorithm.PredicateFailureReason,
|
||||||
|
@ -108,8 +132,8 @@ func (ec *EquivalenceCache) updateResult(
|
||||||
cache schedulercache.Cache,
|
cache schedulercache.Cache,
|
||||||
nodeInfo *schedulercache.NodeInfo,
|
nodeInfo *schedulercache.NodeInfo,
|
||||||
) {
|
) {
|
||||||
ec.mu.Lock()
|
c.mu.Lock()
|
||||||
defer ec.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
if nodeInfo == nil || nodeInfo.Node() == nil {
|
if nodeInfo == nil || nodeInfo.Node() == nil {
|
||||||
// This may happen during tests.
|
// This may happen during tests.
|
||||||
return
|
return
|
||||||
|
@ -119,19 +143,19 @@ func (ec *EquivalenceCache) updateResult(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
nodeName := nodeInfo.Node().GetName()
|
nodeName := nodeInfo.Node().GetName()
|
||||||
if _, exist := ec.cache[nodeName]; !exist {
|
if _, exist := c.cache[nodeName]; !exist {
|
||||||
ec.cache[nodeName] = make(predicateMap)
|
c.cache[nodeName] = make(predicateMap)
|
||||||
}
|
}
|
||||||
predicateItem := predicateResult{
|
predicateItem := predicateResult{
|
||||||
Fit: fit,
|
Fit: fit,
|
||||||
FailReasons: reasons,
|
FailReasons: reasons,
|
||||||
}
|
}
|
||||||
// if cached predicate map already exists, just update the predicate by key
|
// if cached predicate map already exists, just update the predicate by key
|
||||||
if predicates, ok := ec.cache[nodeName][predicateKey]; ok {
|
if predicates, ok := c.cache[nodeName][predicateKey]; ok {
|
||||||
// maps in golang are references, no need to add them back
|
// maps in golang are references, no need to add them back
|
||||||
predicates[equivalenceHash] = predicateItem
|
predicates[equivalenceHash] = predicateItem
|
||||||
} else {
|
} else {
|
||||||
ec.cache[nodeName][predicateKey] =
|
c.cache[nodeName][predicateKey] =
|
||||||
resultMap{
|
resultMap{
|
||||||
equivalenceHash: predicateItem,
|
equivalenceHash: predicateItem,
|
||||||
}
|
}
|
||||||
|
@ -141,27 +165,27 @@ func (ec *EquivalenceCache) updateResult(
|
||||||
|
|
||||||
// lookupResult returns cached predicate results and a bool saying whether a
|
// lookupResult returns cached predicate results and a bool saying whether a
|
||||||
// cache entry was found.
|
// cache entry was found.
|
||||||
func (ec *EquivalenceCache) lookupResult(
|
func (c *Cache) lookupResult(
|
||||||
podName, nodeName, predicateKey string,
|
podName, nodeName, predicateKey string,
|
||||||
equivalenceHash uint64,
|
equivalenceHash uint64,
|
||||||
) (value predicateResult, ok bool) {
|
) (value predicateResult, ok bool) {
|
||||||
ec.mu.RLock()
|
c.mu.RLock()
|
||||||
defer ec.mu.RUnlock()
|
defer c.mu.RUnlock()
|
||||||
glog.V(5).Infof("Begin to calculate predicate: %v for pod: %s on node: %s based on equivalence cache",
|
glog.V(5).Infof("Begin to calculate predicate: %v for pod: %s on node: %s based on equivalence cache",
|
||||||
predicateKey, podName, nodeName)
|
predicateKey, podName, nodeName)
|
||||||
value, ok = ec.cache[nodeName][predicateKey][equivalenceHash]
|
value, ok = c.cache[nodeName][predicateKey][equivalenceHash]
|
||||||
return value, ok
|
return value, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvalidatePredicates clears all cached results for the given predicates.
|
// InvalidatePredicates clears all cached results for the given predicates.
|
||||||
func (ec *EquivalenceCache) InvalidatePredicates(predicateKeys sets.String) {
|
func (c *Cache) InvalidatePredicates(predicateKeys sets.String) {
|
||||||
if len(predicateKeys) == 0 {
|
if len(predicateKeys) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ec.mu.Lock()
|
c.mu.Lock()
|
||||||
defer ec.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
// ec.cache uses nodeName as key, so we just iterate it and invalid given predicates
|
// c.cache uses nodeName as key, so we just iterate it and invalid given predicates
|
||||||
for _, predicates := range ec.cache {
|
for _, predicates := range c.cache {
|
||||||
for predicateKey := range predicateKeys {
|
for predicateKey := range predicateKeys {
|
||||||
delete(predicates, predicateKey)
|
delete(predicates, predicateKey)
|
||||||
}
|
}
|
||||||
|
@ -170,30 +194,30 @@ func (ec *EquivalenceCache) InvalidatePredicates(predicateKeys sets.String) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvalidatePredicatesOnNode clears cached results for the given predicates on one node.
|
// InvalidatePredicatesOnNode clears cached results for the given predicates on one node.
|
||||||
func (ec *EquivalenceCache) InvalidatePredicatesOnNode(nodeName string, predicateKeys sets.String) {
|
func (c *Cache) InvalidatePredicatesOnNode(nodeName string, predicateKeys sets.String) {
|
||||||
if len(predicateKeys) == 0 {
|
if len(predicateKeys) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ec.mu.Lock()
|
c.mu.Lock()
|
||||||
defer ec.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
for predicateKey := range predicateKeys {
|
for predicateKey := range predicateKeys {
|
||||||
delete(ec.cache[nodeName], predicateKey)
|
delete(c.cache[nodeName], predicateKey)
|
||||||
}
|
}
|
||||||
glog.V(5).Infof("Done invalidating cached predicates: %v on node: %s", predicateKeys, nodeName)
|
glog.V(5).Infof("Done invalidating cached predicates: %v on node: %s", predicateKeys, nodeName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvalidateAllPredicatesOnNode clears all cached results for one node.
|
// InvalidateAllPredicatesOnNode clears all cached results for one node.
|
||||||
func (ec *EquivalenceCache) InvalidateAllPredicatesOnNode(nodeName string) {
|
func (c *Cache) InvalidateAllPredicatesOnNode(nodeName string) {
|
||||||
ec.mu.Lock()
|
c.mu.Lock()
|
||||||
defer ec.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
delete(ec.cache, nodeName)
|
delete(c.cache, nodeName)
|
||||||
glog.V(5).Infof("Done invalidating all cached predicates on node: %s", nodeName)
|
glog.V(5).Infof("Done invalidating all cached predicates on node: %s", nodeName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvalidateCachedPredicateItemForPodAdd is a wrapper of
|
// InvalidateCachedPredicateItemForPodAdd is a wrapper of
|
||||||
// InvalidateCachedPredicateItem for pod add case
|
// InvalidateCachedPredicateItem for pod add case
|
||||||
// TODO: This logic does not belong with the equivalence cache implementation.
|
// TODO: This does not belong with the equivalence cache implementation.
|
||||||
func (ec *EquivalenceCache) InvalidateCachedPredicateItemForPodAdd(pod *v1.Pod, nodeName string) {
|
func (c *Cache) InvalidateCachedPredicateItemForPodAdd(pod *v1.Pod, nodeName string) {
|
||||||
// MatchInterPodAffinity: we assume scheduler can make sure newly bound pod
|
// MatchInterPodAffinity: we assume scheduler can make sure newly bound pod
|
||||||
// will not break the existing inter pod affinity. So we does not need to
|
// will not break the existing inter pod affinity. So we does not need to
|
||||||
// invalidate MatchInterPodAffinity when pod added.
|
// invalidate MatchInterPodAffinity when pod added.
|
||||||
|
@ -226,30 +250,7 @@ func (ec *EquivalenceCache) InvalidateCachedPredicateItemForPodAdd(pod *v1.Pod,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ec.InvalidatePredicatesOnNode(nodeName, invalidPredicates)
|
c.InvalidatePredicatesOnNode(nodeName, invalidPredicates)
|
||||||
}
|
|
||||||
|
|
||||||
// EquivalenceClassInfo holds equivalence hash which is used for checking
|
|
||||||
// equivalence cache. We will pass this to podFitsOnNode to ensure equivalence
|
|
||||||
// hash is only calculated per schedule.
|
|
||||||
type EquivalenceClassInfo struct {
|
|
||||||
// Equivalence hash.
|
|
||||||
hash uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetEquivalenceClassInfo returns a hash of the given pod. The hashing function
|
|
||||||
// returns the same value for any two pods that are equivalent from the
|
|
||||||
// perspective of scheduling.
|
|
||||||
func (ec *EquivalenceCache) GetEquivalenceClassInfo(pod *v1.Pod) *EquivalenceClassInfo {
|
|
||||||
equivalencePod := getEquivalencePod(pod)
|
|
||||||
if equivalencePod != nil {
|
|
||||||
hash := fnv.New32a()
|
|
||||||
hashutil.DeepHashObject(hash, equivalencePod)
|
|
||||||
return &EquivalenceClassInfo{
|
|
||||||
hash: uint64(hash.Sum32()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// equivalencePod is the set of pod attributes which must match for two pods to
|
// equivalencePod is the set of pod attributes which must match for two pods to
|
||||||
|
|
|
@ -247,8 +247,8 @@ func TestRunPredicate(t *testing.T) {
|
||||||
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "p1"}}
|
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "p1"}}
|
||||||
meta := algorithm.EmptyPredicateMetadataProducer(nil, nil)
|
meta := algorithm.EmptyPredicateMetadataProducer(nil, nil)
|
||||||
|
|
||||||
ecache := NewEquivalenceCache()
|
ecache := NewCache()
|
||||||
equivClass := ecache.GetEquivalenceClassInfo(pod)
|
equivClass := NewClass(pod)
|
||||||
if test.expectCacheHit {
|
if test.expectCacheHit {
|
||||||
ecache.updateResult(pod.Name, "testPredicate", test.expectFit, test.expectedReasons, equivClass.hash, test.cache, node)
|
ecache.updateResult(pod.Name, "testPredicate", test.expectFit, test.expectedReasons, equivClass.hash, test.cache, node)
|
||||||
}
|
}
|
||||||
|
@ -339,7 +339,7 @@ func TestUpdateResult(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
ecache := NewEquivalenceCache()
|
ecache := NewCache()
|
||||||
if test.expectPredicateMap {
|
if test.expectPredicateMap {
|
||||||
ecache.cache[test.nodeName] = make(predicateMap)
|
ecache.cache[test.nodeName] = make(predicateMap)
|
||||||
predicateItem := predicateResult{
|
predicateItem := predicateResult{
|
||||||
|
@ -473,7 +473,7 @@ func TestLookupResult(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
ecache := NewEquivalenceCache()
|
ecache := NewCache()
|
||||||
node := schedulercache.NewNodeInfo()
|
node := schedulercache.NewNodeInfo()
|
||||||
node.SetNode(&v1.Node{ObjectMeta: metav1.ObjectMeta{Name: test.nodeName}})
|
node.SetNode(&v1.Node{ObjectMeta: metav1.ObjectMeta{Name: test.nodeName}})
|
||||||
// set cached item to equivalence cache
|
// set cached item to equivalence cache
|
||||||
|
@ -527,9 +527,6 @@ func TestLookupResult(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetEquivalenceHash(t *testing.T) {
|
func TestGetEquivalenceHash(t *testing.T) {
|
||||||
|
|
||||||
ecache := NewEquivalenceCache()
|
|
||||||
|
|
||||||
pod1 := makeBasicPod("pod1")
|
pod1 := makeBasicPod("pod1")
|
||||||
pod2 := makeBasicPod("pod2")
|
pod2 := makeBasicPod("pod2")
|
||||||
|
|
||||||
|
@ -620,7 +617,7 @@ func TestGetEquivalenceHash(t *testing.T) {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
for i, podInfo := range test.podInfoList {
|
for i, podInfo := range test.podInfoList {
|
||||||
testPod := podInfo.pod
|
testPod := podInfo.pod
|
||||||
eclassInfo := ecache.GetEquivalenceClassInfo(testPod)
|
eclassInfo := NewClass(testPod)
|
||||||
if eclassInfo == nil && podInfo.hashIsValid {
|
if eclassInfo == nil && podInfo.hashIsValid {
|
||||||
t.Errorf("Failed: pod %v is expected to have valid hash", testPod)
|
t.Errorf("Failed: pod %v is expected to have valid hash", testPod)
|
||||||
}
|
}
|
||||||
|
@ -688,7 +685,7 @@ func TestInvalidateCachedPredicateItemOfAllNodes(t *testing.T) {
|
||||||
cache: &upToDateCache{},
|
cache: &upToDateCache{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ecache := NewEquivalenceCache()
|
ecache := NewCache()
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
node := schedulercache.NewNodeInfo()
|
node := schedulercache.NewNodeInfo()
|
||||||
|
@ -760,7 +757,7 @@ func TestInvalidateAllCachedPredicateItemOfNode(t *testing.T) {
|
||||||
cache: &upToDateCache{},
|
cache: &upToDateCache{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ecache := NewEquivalenceCache()
|
ecache := NewCache()
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
node := schedulercache.NewNodeInfo()
|
node := schedulercache.NewNodeInfo()
|
||||||
|
|
|
@ -86,7 +86,7 @@ func (f *FitError) Error() string {
|
||||||
|
|
||||||
type genericScheduler struct {
|
type genericScheduler struct {
|
||||||
cache schedulercache.Cache
|
cache schedulercache.Cache
|
||||||
equivalenceCache *equivalence.EquivalenceCache
|
equivalenceCache *equivalence.Cache
|
||||||
schedulingQueue SchedulingQueue
|
schedulingQueue SchedulingQueue
|
||||||
predicates map[string]algorithm.FitPredicate
|
predicates map[string]algorithm.FitPredicate
|
||||||
priorityMetaProducer algorithm.PriorityMetadataProducer
|
priorityMetaProducer algorithm.PriorityMetadataProducer
|
||||||
|
@ -343,10 +343,10 @@ func (g *genericScheduler) findNodesThatFit(pod *v1.Pod, nodes []*v1.Node) ([]*v
|
||||||
// We can use the same metadata producer for all nodes.
|
// We can use the same metadata producer for all nodes.
|
||||||
meta := g.predicateMetaProducer(pod, g.cachedNodeInfoMap)
|
meta := g.predicateMetaProducer(pod, g.cachedNodeInfoMap)
|
||||||
|
|
||||||
var equivCacheInfo *equivalence.EquivalenceClassInfo
|
var equivClass *equivalence.Class
|
||||||
if g.equivalenceCache != nil {
|
if g.equivalenceCache != nil {
|
||||||
// getEquivalenceClassInfo will return immediately if no equivalence pod found
|
// getEquivalenceClassInfo will return immediately if no equivalence pod found
|
||||||
equivCacheInfo = g.equivalenceCache.GetEquivalenceClassInfo(pod)
|
equivClass = equivalence.NewClass(pod)
|
||||||
}
|
}
|
||||||
|
|
||||||
checkNode := func(i int) {
|
checkNode := func(i int) {
|
||||||
|
@ -360,7 +360,7 @@ func (g *genericScheduler) findNodesThatFit(pod *v1.Pod, nodes []*v1.Node) ([]*v
|
||||||
g.equivalenceCache,
|
g.equivalenceCache,
|
||||||
g.schedulingQueue,
|
g.schedulingQueue,
|
||||||
g.alwaysCheckAllPredicates,
|
g.alwaysCheckAllPredicates,
|
||||||
equivCacheInfo,
|
equivClass,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
predicateResultLock.Lock()
|
predicateResultLock.Lock()
|
||||||
|
@ -460,10 +460,10 @@ func podFitsOnNode(
|
||||||
info *schedulercache.NodeInfo,
|
info *schedulercache.NodeInfo,
|
||||||
predicateFuncs map[string]algorithm.FitPredicate,
|
predicateFuncs map[string]algorithm.FitPredicate,
|
||||||
cache schedulercache.Cache,
|
cache schedulercache.Cache,
|
||||||
ecache *equivalence.EquivalenceCache,
|
ecache *equivalence.Cache,
|
||||||
queue SchedulingQueue,
|
queue SchedulingQueue,
|
||||||
alwaysCheckAllPredicates bool,
|
alwaysCheckAllPredicates bool,
|
||||||
equivCacheInfo *equivalence.EquivalenceClassInfo,
|
equivClass *equivalence.Class,
|
||||||
) (bool, []algorithm.PredicateFailureReason, error) {
|
) (bool, []algorithm.PredicateFailureReason, error) {
|
||||||
var (
|
var (
|
||||||
eCacheAvailable bool
|
eCacheAvailable bool
|
||||||
|
@ -500,7 +500,7 @@ func podFitsOnNode(
|
||||||
// Bypass eCache if node has any nominated pods.
|
// Bypass eCache if node has any nominated pods.
|
||||||
// TODO(bsalamat): consider using eCache and adding proper eCache invalidations
|
// TODO(bsalamat): consider using eCache and adding proper eCache invalidations
|
||||||
// when pods are nominated or their nominations change.
|
// when pods are nominated or their nominations change.
|
||||||
eCacheAvailable = equivCacheInfo != nil && !podsAdded
|
eCacheAvailable = equivClass != nil && !podsAdded
|
||||||
for _, predicateKey := range predicates.Ordering() {
|
for _, predicateKey := range predicates.Ordering() {
|
||||||
var (
|
var (
|
||||||
fit bool
|
fit bool
|
||||||
|
@ -510,7 +510,7 @@ func podFitsOnNode(
|
||||||
//TODO (yastij) : compute average predicate restrictiveness to export it as Prometheus metric
|
//TODO (yastij) : compute average predicate restrictiveness to export it as Prometheus metric
|
||||||
if predicate, exist := predicateFuncs[predicateKey]; exist {
|
if predicate, exist := predicateFuncs[predicateKey]; exist {
|
||||||
if eCacheAvailable {
|
if eCacheAvailable {
|
||||||
fit, reasons, err = ecache.RunPredicate(predicate, predicateKey, pod, metaToUse, nodeInfoToUse, equivCacheInfo, cache)
|
fit, reasons, err = ecache.RunPredicate(predicate, predicateKey, pod, metaToUse, nodeInfoToUse, equivClass, cache)
|
||||||
} else {
|
} else {
|
||||||
fit, reasons, err = predicate(pod, metaToUse, nodeInfoToUse)
|
fit, reasons, err = predicate(pod, metaToUse, nodeInfoToUse)
|
||||||
}
|
}
|
||||||
|
@ -1057,7 +1057,7 @@ func podPassesBasicChecks(pod *v1.Pod, pvcLister corelisters.PersistentVolumeCla
|
||||||
// NewGenericScheduler creates a genericScheduler object.
|
// NewGenericScheduler creates a genericScheduler object.
|
||||||
func NewGenericScheduler(
|
func NewGenericScheduler(
|
||||||
cache schedulercache.Cache,
|
cache schedulercache.Cache,
|
||||||
eCache *equivalence.EquivalenceCache,
|
eCache *equivalence.Cache,
|
||||||
podQueue SchedulingQueue,
|
podQueue SchedulingQueue,
|
||||||
predicates map[string]algorithm.FitPredicate,
|
predicates map[string]algorithm.FitPredicate,
|
||||||
predicateMetaProducer algorithm.PredicateMetadataProducer,
|
predicateMetaProducer algorithm.PredicateMetadataProducer,
|
||||||
|
|
|
@ -1367,10 +1367,10 @@ func (c *syncingMockCache) UpdateNodeNameToInfoMap(infoMap map[string]*scheduler
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestEquivalenceCacheInvalidationRace tests that equivalence cache invalidation is correctly
|
// TestCacheInvalidationRace tests that equivalence cache invalidation is correctly
|
||||||
// handled when an invalidation event happens early in a scheduling cycle. Specifically, the event
|
// handled when an invalidation event happens early in a scheduling cycle. Specifically, the event
|
||||||
// occurs after schedulercache is snapshotted and before equivalence cache lock is acquired.
|
// occurs after schedulercache is snapshotted and before equivalence cache lock is acquired.
|
||||||
func TestEquivalenceCacheInvalidationRace(t *testing.T) {
|
func TestCacheInvalidationRace(t *testing.T) {
|
||||||
// Create a predicate that returns false the first time and true on subsequent calls.
|
// Create a predicate that returns false the first time and true on subsequent calls.
|
||||||
podWillFit := false
|
podWillFit := false
|
||||||
var callCount int
|
var callCount int
|
||||||
|
@ -1394,7 +1394,7 @@ func TestEquivalenceCacheInvalidationRace(t *testing.T) {
|
||||||
cacheInvalidated: make(chan struct{}),
|
cacheInvalidated: make(chan struct{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
eCache := equivalence.NewEquivalenceCache()
|
eCache := equivalence.NewCache()
|
||||||
// Ensure that equivalence cache invalidation happens after the scheduling cycle starts, but before
|
// Ensure that equivalence cache invalidation happens after the scheduling cycle starts, but before
|
||||||
// the equivalence cache would be updated.
|
// the equivalence cache would be updated.
|
||||||
go func() {
|
go func() {
|
||||||
|
|
|
@ -124,7 +124,7 @@ type configFactory struct {
|
||||||
hardPodAffinitySymmetricWeight int32
|
hardPodAffinitySymmetricWeight int32
|
||||||
|
|
||||||
// Equivalence class cache
|
// Equivalence class cache
|
||||||
equivalencePodCache *equivalence.EquivalenceCache
|
equivalencePodCache *equivalence.Cache
|
||||||
|
|
||||||
// Enable equivalence class cache
|
// Enable equivalence class cache
|
||||||
enableEquivalenceClassCache bool
|
enableEquivalenceClassCache bool
|
||||||
|
@ -1075,7 +1075,7 @@ func (c *configFactory) CreateFromKeys(predicateKeys, priorityKeys sets.String,
|
||||||
|
|
||||||
// Init equivalence class cache
|
// Init equivalence class cache
|
||||||
if c.enableEquivalenceClassCache {
|
if c.enableEquivalenceClassCache {
|
||||||
c.equivalencePodCache = equivalence.NewEquivalenceCache()
|
c.equivalencePodCache = equivalence.NewCache()
|
||||||
glog.Info("Created equivalence class cache")
|
glog.Info("Created equivalence class cache")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ type Config struct {
|
||||||
SchedulerCache schedulercache.Cache
|
SchedulerCache schedulercache.Cache
|
||||||
// Ecache is used for optimistically invalid affected cache items after
|
// Ecache is used for optimistically invalid affected cache items after
|
||||||
// successfully binding a pod
|
// successfully binding a pod
|
||||||
Ecache *equivalence.EquivalenceCache
|
Ecache *equivalence.Cache
|
||||||
NodeLister algorithm.NodeLister
|
NodeLister algorithm.NodeLister
|
||||||
Algorithm algorithm.ScheduleAlgorithm
|
Algorithm algorithm.ScheduleAlgorithm
|
||||||
GetBinder func(pod *v1.Pod) Binder
|
GetBinder func(pod *v1.Pod) Binder
|
||||||
|
|
Loading…
Reference in New Issue