Commit a51f266e authored by Wojciech Tyczynski's avatar Wojciech Tyczynski

Remove nodeName from predicate signature.

parent 7e462c23
...@@ -2339,7 +2339,7 @@ func (kl *Kubelet) canAdmitPod(pods []*api.Pod, pod *api.Pod) (bool, string, str ...@@ -2339,7 +2339,7 @@ func (kl *Kubelet) canAdmitPod(pods []*api.Pod, pod *api.Pod) (bool, string, str
} }
nodeInfo := schedulercache.NewNodeInfo(otherPods...) nodeInfo := schedulercache.NewNodeInfo(otherPods...)
nodeInfo.SetNode(node) nodeInfo.SetNode(node)
fit, err := predicates.GeneralPredicates(pod, kl.nodeName, nodeInfo) fit, err := predicates.GeneralPredicates(pod, nodeInfo)
if !fit { if !fit {
if re, ok := err.(*predicates.PredicateFailureError); ok { if re, ok := err.(*predicates.PredicateFailureError); ok {
reason := re.PredicateName reason := re.PredicateName
......
...@@ -101,7 +101,7 @@ func isVolumeConflict(volume api.Volume, pod *api.Pod) bool { ...@@ -101,7 +101,7 @@ func isVolumeConflict(volume api.Volume, pod *api.Pod) bool {
// - AWS EBS forbids any two pods mounting the same volume ID // - AWS EBS forbids any two pods mounting the same volume ID
// - Ceph RBD forbids if any two pods share at least same monitor, and match pool and image. // - Ceph RBD forbids if any two pods share at least same monitor, and match pool and image.
// TODO: migrate this into some per-volume specific code? // TODO: migrate this into some per-volume specific code?
func NoDiskConflict(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) { func NoDiskConflict(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) {
for _, v := range pod.Spec.Volumes { for _, v := range pod.Spec.Volumes {
for _, ev := range nodeInfo.Pods() { for _, ev := range nodeInfo.Pods() {
if isVolumeConflict(v, ev) { if isVolumeConflict(v, ev) {
...@@ -177,7 +177,7 @@ func (c *MaxPDVolumeCountChecker) filterVolumes(volumes []api.Volume, namespace ...@@ -177,7 +177,7 @@ func (c *MaxPDVolumeCountChecker) filterVolumes(volumes []api.Volume, namespace
return nil return nil
} }
func (c *MaxPDVolumeCountChecker) predicate(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) { func (c *MaxPDVolumeCountChecker) predicate(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) {
newVolumes := make(map[string]bool) newVolumes := make(map[string]bool)
if err := c.filterVolumes(pod.Spec.Volumes, pod.Namespace, newVolumes); err != nil { if err := c.filterVolumes(pod.Spec.Volumes, pod.Namespace, newVolumes); err != nil {
return false, err return false, err
...@@ -275,10 +275,10 @@ func NewVolumeZonePredicate(pvInfo PersistentVolumeInfo, pvcInfo PersistentVolum ...@@ -275,10 +275,10 @@ func NewVolumeZonePredicate(pvInfo PersistentVolumeInfo, pvcInfo PersistentVolum
return c.predicate return c.predicate
} }
func (c *VolumeZoneChecker) predicate(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) { func (c *VolumeZoneChecker) predicate(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) {
node := nodeInfo.Node() node := nodeInfo.Node()
if node == nil { if node == nil {
return false, fmt.Errorf("node not found: %q", nodeName) return false, fmt.Errorf("node not found")
} }
nodeConstraints := make(map[string]string) nodeConstraints := make(map[string]string)
...@@ -335,7 +335,7 @@ func (c *VolumeZoneChecker) predicate(pod *api.Pod, nodeName string, nodeInfo *s ...@@ -335,7 +335,7 @@ func (c *VolumeZoneChecker) predicate(pod *api.Pod, nodeName string, nodeInfo *s
} }
nodeV, _ := nodeConstraints[k] nodeV, _ := nodeConstraints[k]
if v != nodeV { if v != nodeV {
glog.V(2).Infof("Won't schedule pod %q onto node %q due to volume %q (mismatch on %q)", pod.Name, nodeName, pvName, k) glog.V(2).Infof("Won't schedule pod %q onto node %q due to volume %q (mismatch on %q)", pod.Name, node.Name, pvName, k)
return false, ErrVolumeZoneConflict return false, ErrVolumeZoneConflict
} }
} }
...@@ -391,10 +391,10 @@ func podName(pod *api.Pod) string { ...@@ -391,10 +391,10 @@ func podName(pod *api.Pod) string {
return pod.Namespace + "/" + pod.Name return pod.Namespace + "/" + pod.Name
} }
func podFitsResourcesInternal(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) { func PodFitsResources(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) {
node := nodeInfo.Node() node := nodeInfo.Node()
if node == nil { if node == nil {
return false, fmt.Errorf("node not found: %q", nodeName) return false, fmt.Errorf("node not found")
} }
allocatable := node.Status.Allocatable allocatable := node.Status.Allocatable
allowedPodNumber := allocatable.Pods().Value() allowedPodNumber := allocatable.Pods().Value()
...@@ -419,14 +419,10 @@ func podFitsResourcesInternal(pod *api.Pod, nodeName string, nodeInfo *scheduler ...@@ -419,14 +419,10 @@ func podFitsResourcesInternal(pod *api.Pod, nodeName string, nodeInfo *scheduler
newInsufficientResourceError(memoryResoureceName, podRequest.memory, nodeInfo.RequestedResource().Memory, totalMemory) newInsufficientResourceError(memoryResoureceName, podRequest.memory, nodeInfo.RequestedResource().Memory, totalMemory)
} }
glog.V(10).Infof("Schedule Pod %+v on Node %+v is allowed, Node is running only %v out of %v Pods.", glog.V(10).Infof("Schedule Pod %+v on Node %+v is allowed, Node is running only %v out of %v Pods.",
podName(pod), nodeName, len(nodeInfo.Pods()), allowedPodNumber) podName(pod), node.Name, len(nodeInfo.Pods()), allowedPodNumber)
return true, nil return true, nil
} }
func PodFitsResources(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) {
return podFitsResourcesInternal(pod, nodeName, nodeInfo)
}
// nodeMatchesNodeSelectorTerms checks if a node's labels satisfy a list of node selector terms, // nodeMatchesNodeSelectorTerms checks if a node's labels satisfy a list of node selector terms,
// terms are ORed, and an emtpy a list of terms will match nothing. // terms are ORed, and an emtpy a list of terms will match nothing.
func nodeMatchesNodeSelectorTerms(node *api.Node, nodeSelectorTerms []api.NodeSelectorTerm) bool { func nodeMatchesNodeSelectorTerms(node *api.Node, nodeSelectorTerms []api.NodeSelectorTerm) bool {
...@@ -496,10 +492,10 @@ func PodMatchesNodeLabels(pod *api.Pod, node *api.Node) bool { ...@@ -496,10 +492,10 @@ func PodMatchesNodeLabels(pod *api.Pod, node *api.Node) bool {
return nodeAffinityMatches return nodeAffinityMatches
} }
func PodSelectorMatches(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) { func PodSelectorMatches(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) {
node := nodeInfo.Node() node := nodeInfo.Node()
if node == nil { if node == nil {
return false, fmt.Errorf("node not found: %q", nodeName) return false, fmt.Errorf("node not found")
} }
if PodMatchesNodeLabels(pod, node) { if PodMatchesNodeLabels(pod, node) {
return true, nil return true, nil
...@@ -507,11 +503,15 @@ func PodSelectorMatches(pod *api.Pod, nodeName string, nodeInfo *schedulercache. ...@@ -507,11 +503,15 @@ func PodSelectorMatches(pod *api.Pod, nodeName string, nodeInfo *schedulercache.
return false, ErrNodeSelectorNotMatch return false, ErrNodeSelectorNotMatch
} }
func PodFitsHost(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) { func PodFitsHost(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) {
if len(pod.Spec.NodeName) == 0 { if len(pod.Spec.NodeName) == 0 {
return true, nil return true, nil
} }
if pod.Spec.NodeName == nodeName { node := nodeInfo.Node()
if node == nil {
return false, fmt.Errorf("node not found")
}
if pod.Spec.NodeName == node.Name {
return true, nil return true, nil
} }
return false, ErrPodNotMatchHostName return false, ErrPodNotMatchHostName
...@@ -542,10 +542,10 @@ func NewNodeLabelPredicate(labels []string, presence bool) algorithm.FitPredicat ...@@ -542,10 +542,10 @@ func NewNodeLabelPredicate(labels []string, presence bool) algorithm.FitPredicat
// Alternately, eliminating nodes that have a certain label, regardless of value, is also useful // Alternately, eliminating nodes that have a certain label, regardless of value, is also useful
// A node may have a label with "retiring" as key and the date as the value // A node may have a label with "retiring" as key and the date as the value
// and it may be desirable to avoid scheduling new pods on this node // and it may be desirable to avoid scheduling new pods on this node
func (n *NodeLabelChecker) CheckNodeLabelPresence(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) { func (n *NodeLabelChecker) CheckNodeLabelPresence(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) {
node := nodeInfo.Node() node := nodeInfo.Node()
if node == nil { if node == nil {
return false, fmt.Errorf("node not found: %q", nodeName) return false, fmt.Errorf("node not found")
} }
var exists bool var exists bool
...@@ -585,7 +585,7 @@ func NewServiceAffinityPredicate(podLister algorithm.PodLister, serviceLister al ...@@ -585,7 +585,7 @@ func NewServiceAffinityPredicate(podLister algorithm.PodLister, serviceLister al
// - L is listed in the ServiceAffinity object that is passed into the function // - L is listed in the ServiceAffinity object that is passed into the function
// - the pod does not have any NodeSelector for L // - the pod does not have any NodeSelector for L
// - some other pod from the same service is already scheduled onto a node that has value V for label L // - some other pod from the same service is already scheduled onto a node that has value V for label L
func (s *ServiceAffinity) CheckServiceAffinity(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) { func (s *ServiceAffinity) CheckServiceAffinity(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) {
var affinitySelector labels.Selector var affinitySelector labels.Selector
// check if the pod being scheduled has the affinity labels specified in its NodeSelector // check if the pod being scheduled has the affinity labels specified in its NodeSelector
...@@ -645,9 +645,9 @@ func (s *ServiceAffinity) CheckServiceAffinity(pod *api.Pod, nodeName string, no ...@@ -645,9 +645,9 @@ func (s *ServiceAffinity) CheckServiceAffinity(pod *api.Pod, nodeName string, no
affinitySelector = labels.Set(affinityLabels).AsSelector() affinitySelector = labels.Set(affinityLabels).AsSelector()
} }
node, err := s.nodeInfo.GetNodeInfo(nodeName) node := nodeInfo.Node()
if err != nil { if node == nil {
return false, err return false, fmt.Errorf("node not found")
} }
// check if the node matches the selector // check if the node matches the selector
...@@ -657,7 +657,7 @@ func (s *ServiceAffinity) CheckServiceAffinity(pod *api.Pod, nodeName string, no ...@@ -657,7 +657,7 @@ func (s *ServiceAffinity) CheckServiceAffinity(pod *api.Pod, nodeName string, no
return false, ErrServiceAffinityViolated return false, ErrServiceAffinityViolated
} }
func PodFitsHostPorts(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) { func PodFitsHostPorts(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) {
wantPorts := getUsedPorts(pod) wantPorts := getUsedPorts(pod)
if len(wantPorts) == 0 { if len(wantPorts) == 0 {
return true, nil return true, nil
...@@ -703,21 +703,21 @@ func haveSame(a1, a2 []string) bool { ...@@ -703,21 +703,21 @@ func haveSame(a1, a2 []string) bool {
return false return false
} }
func GeneralPredicates(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) { func GeneralPredicates(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) {
fit, err := podFitsResourcesInternal(pod, nodeName, nodeInfo) fit, err := PodFitsResources(pod, nodeInfo)
if !fit { if !fit {
return fit, err return fit, err
} }
fit, err = PodFitsHost(pod, nodeName, nodeInfo) fit, err = PodFitsHost(pod, nodeInfo)
if !fit { if !fit {
return fit, err return fit, err
} }
fit, err = PodFitsHostPorts(pod, nodeName, nodeInfo) fit, err = PodFitsHostPorts(pod, nodeInfo)
if !fit { if !fit {
return fit, err return fit, err
} }
fit, err = PodSelectorMatches(pod, nodeName, nodeInfo) fit, err = PodSelectorMatches(pod, nodeInfo)
if !fit { if !fit {
return fit, err return fit, err
} }
...@@ -739,10 +739,10 @@ func NewPodAffinityPredicate(info NodeInfo, podLister algorithm.PodLister, failu ...@@ -739,10 +739,10 @@ func NewPodAffinityPredicate(info NodeInfo, podLister algorithm.PodLister, failu
return checker.InterPodAffinityMatches return checker.InterPodAffinityMatches
} }
func (checker *PodAffinityChecker) InterPodAffinityMatches(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) { func (checker *PodAffinityChecker) InterPodAffinityMatches(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) {
node, err := checker.info.GetNodeInfo(nodeName) node := nodeInfo.Node()
if err != nil { if node == nil {
return false, err return false, fmt.Errorf("node not found")
} }
allPods, err := checker.podLister.List(labels.Everything()) allPods, err := checker.podLister.List(labels.Everything())
if err != nil { if err != nil {
......
...@@ -24,7 +24,7 @@ import ( ...@@ -24,7 +24,7 @@ import (
// FitPredicate is a function that indicates if a pod fits into an existing node. // FitPredicate is a function that indicates if a pod fits into an existing node.
// The failure information is given by the error. // The failure information is given by the error.
type FitPredicate func(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) type FitPredicate func(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error)
type PriorityFunction func(pod *api.Pod, nodeNameToInfo map[string]*schedulercache.NodeInfo, nodeLister NodeLister) (schedulerapi.HostPriorityList, error) type PriorityFunction func(pod *api.Pod, nodeNameToInfo map[string]*schedulercache.NodeInfo, nodeLister NodeLister) (schedulerapi.HostPriorityList, error)
......
...@@ -116,11 +116,11 @@ func TestCreateFromEmptyConfig(t *testing.T) { ...@@ -116,11 +116,11 @@ func TestCreateFromEmptyConfig(t *testing.T) {
factory.CreateFromConfig(policy) factory.CreateFromConfig(policy)
} }
func PredicateOne(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) { func PredicateOne(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) {
return true, nil return true, nil
} }
func PredicateTwo(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) { func PredicateTwo(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) {
return true, nil return true, nil
} }
......
...@@ -144,7 +144,7 @@ func findNodesThatFit(pod *api.Pod, nodeNameToInfo map[string]*schedulercache.No ...@@ -144,7 +144,7 @@ func findNodesThatFit(pod *api.Pod, nodeNameToInfo map[string]*schedulercache.No
checkNode := func(i int) { checkNode := func(i int) {
nodeName := nodes.Items[i].Name nodeName := nodes.Items[i].Name
fits, failedPredicate, err := podFitsOnNode(pod, nodeName, nodeNameToInfo[nodeName], predicateFuncs) fits, failedPredicate, err := podFitsOnNode(pod, nodeNameToInfo[nodeName], predicateFuncs)
predicateResultLock.Lock() predicateResultLock.Lock()
defer predicateResultLock.Unlock() defer predicateResultLock.Unlock()
...@@ -179,9 +179,9 @@ func findNodesThatFit(pod *api.Pod, nodeNameToInfo map[string]*schedulercache.No ...@@ -179,9 +179,9 @@ func findNodesThatFit(pod *api.Pod, nodeNameToInfo map[string]*schedulercache.No
} }
// Checks whether node with a given name and NodeInfo satisfies all predicateFuncs. // Checks whether node with a given name and NodeInfo satisfies all predicateFuncs.
func podFitsOnNode(pod *api.Pod, nodeName string, info *schedulercache.NodeInfo, predicateFuncs map[string]algorithm.FitPredicate) (bool, string, error) { func podFitsOnNode(pod *api.Pod, info *schedulercache.NodeInfo, predicateFuncs map[string]algorithm.FitPredicate) (bool, string, error) {
for _, predicate := range predicateFuncs { for _, predicate := range predicateFuncs {
fit, err := predicate(pod, nodeName, info) fit, err := predicate(pod, info)
if err != nil { if err != nil {
switch e := err.(type) { switch e := err.(type) {
case *predicates.InsufficientResourceError: case *predicates.InsufficientResourceError:
......
...@@ -23,32 +23,37 @@ import ( ...@@ -23,32 +23,37 @@ import (
"reflect" "reflect"
"strconv" "strconv"
"testing" "testing"
"time"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/sets"
"k8s.io/kubernetes/pkg/util/wait"
"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm" "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm"
algorithmpredicates "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates" algorithmpredicates "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates"
schedulerapi "k8s.io/kubernetes/plugin/pkg/scheduler/api" schedulerapi "k8s.io/kubernetes/plugin/pkg/scheduler/api"
"k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache" "k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache"
schedulertesting "k8s.io/kubernetes/plugin/pkg/scheduler/testing"
) )
func falsePredicate(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) { func falsePredicate(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) {
return false, algorithmpredicates.ErrFakePredicate return false, algorithmpredicates.ErrFakePredicate
} }
func truePredicate(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) { func truePredicate(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) {
return true, nil return true, nil
} }
func matchesPredicate(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) { func matchesPredicate(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) {
if pod.Name == nodeName { node := nodeInfo.Node()
if node == nil {
return false, fmt.Errorf("node not found")
}
if pod.Name == node.Name {
return true, nil return true, nil
} }
return false, algorithmpredicates.ErrFakePredicate return false, algorithmpredicates.ErrFakePredicate
} }
func hasNoPodsPredicate(pod *api.Pod, nodeName string, nodeInfo *schedulercache.NodeInfo) (bool, error) { func hasNoPodsPredicate(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) {
if len(nodeInfo.Pods()) == 0 { if len(nodeInfo.Pods()) == 0 {
return true, nil return true, nil
} }
...@@ -273,7 +278,14 @@ func TestGenericScheduler(t *testing.T) { ...@@ -273,7 +278,14 @@ func TestGenericScheduler(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
random := rand.New(rand.NewSource(0)) random := rand.New(rand.NewSource(0))
scheduler := NewGenericScheduler(schedulertesting.PodsToCache(test.pods), test.predicates, test.prioritizers, []algorithm.SchedulerExtender{}, random) cache := schedulercache.New(time.Duration(0), wait.NeverStop)
for _, pod := range test.pods {
cache.AddPod(pod)
}
for _, name := range test.nodes {
cache.AddNode(&api.Node{ObjectMeta: api.ObjectMeta{Name: name}})
}
scheduler := NewGenericScheduler(cache, test.predicates, test.prioritizers, []algorithm.SchedulerExtender{}, random)
machine, err := scheduler.Schedule(test.pod, algorithm.FakeNodeLister(makeNodeList(test.nodes))) machine, err := scheduler.Schedule(test.pod, algorithm.FakeNodeLister(makeNodeList(test.nodes)))
if test.expectsErr { if test.expectsErr {
if err == nil { if err == nil {
...@@ -328,6 +340,9 @@ func TestFindFitSomeError(t *testing.T) { ...@@ -328,6 +340,9 @@ func TestFindFitSomeError(t *testing.T) {
"2": schedulercache.NewNodeInfo(), "2": schedulercache.NewNodeInfo(),
"1": schedulercache.NewNodeInfo(pod), "1": schedulercache.NewNodeInfo(pod),
} }
for name := range nodeNameToInfo {
nodeNameToInfo[name].SetNode(&api.Node{ObjectMeta: api.ObjectMeta{Name: name}})
}
_, predicateMap, err := findNodesThatFit(pod, nodeNameToInfo, predicates, makeNodeList(nodes), nil) _, predicateMap, err := findNodesThatFit(pod, nodeNameToInfo, predicates, makeNodeList(nodes), nil)
if err != nil && !reflect.DeepEqual(err, algorithmpredicates.ErrFakePredicate) { if err != nil && !reflect.DeepEqual(err, algorithmpredicates.ErrFakePredicate) {
......
...@@ -35,14 +35,14 @@ var ( ...@@ -35,14 +35,14 @@ var (
// It automatically starts a go routine that manages expiration of assumed pods. // It automatically starts a go routine that manages expiration of assumed pods.
// "ttl" is how long the assumed pod will get expired. // "ttl" is how long the assumed pod will get expired.
// "stop" is the channel that would close the background goroutine. // "stop" is the channel that would close the background goroutine.
func New(ttl time.Duration, stop chan struct{}) Cache { func New(ttl time.Duration, stop <-chan struct{}) Cache {
cache := newSchedulerCache(ttl, cleanAssumedPeriod, stop) cache := newSchedulerCache(ttl, cleanAssumedPeriod, stop)
cache.run() cache.run()
return cache return cache
} }
type schedulerCache struct { type schedulerCache struct {
stop chan struct{} stop <-chan struct{}
ttl time.Duration ttl time.Duration
period time.Duration period time.Duration
...@@ -62,7 +62,7 @@ type podState struct { ...@@ -62,7 +62,7 @@ type podState struct {
deadline *time.Time deadline *time.Time
} }
func newSchedulerCache(ttl, period time.Duration, stop chan struct{}) *schedulerCache { func newSchedulerCache(ttl, period time.Duration, stop <-chan struct{}) *schedulerCache {
return &schedulerCache{ return &schedulerCache{
ttl: ttl, ttl: ttl,
period: period, period: period,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment