Repository: kubernetes/kubernetes
File: pkg/scheduler/eventhandlers.go (Go)

Code before:
		utilruntime.HandleErrorWithLogger(logger, nil, "Cannot convert newObj to *v1.Node", "newObj", newObj)
		return
	}

	logger.V(4).Info("Update event for node", "node", klog.KObj(newNode))
	nodeInfo := sched.Cache.UpdateNode(logger, oldNode, newNode)
	events := framework.NodeSchedulingPropertiesChange(newNode, oldNode)

	// Save the time it takes to update the node in the cache.
	updatingDuration := metrics.SinceInSeconds(start)

	// Only requeue unschedulable pods if the node became more schedulable.
	for _, evt := range events {
		startMoving := time.Now()
		sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, evt, oldNode, newNode, preCheckForNode(logger, nodeInfo))
		movingDuration := metrics.SinceInSeconds(startMoving)

		metrics.EventHandlingLatency.WithLabelValues(evt.Label()).Observe(updatingDuration + movingDuration)
	}
}

func (sched *Scheduler) deleteNodeFromCache(obj interface{}) {
	evt := fwk.ClusterEvent{Resource: fwk.Node, ActionType: fwk.Delete}
	start := time.Now()
	defer func() {
		metrics.EventHandlingLatency.WithLabelValues(evt.Label()).Observe(metrics.SinceInSeconds(start))
	}()

	logger := sched.logger
	var node *v1.Node
	switch t := obj.(type) {
	case *v1.Node:
		node = t
	case cache.DeletedFinalStateUnknown:
		var ok bool
		node, ok = t.Obj.(*v1.Node)
		if !ok {
			utilruntime.HandleErrorWithLogger(logger, nil, "Cannot convert to *v1.Node", "obj", t.Obj)
			return
		}
	default:
		utilruntime.HandleErrorWithLogger(logger, nil, "Cannot convert to *v1.Node", "obj", t)
		return
	}

	sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, evt, node, nil, nil)

	logger.V(3).Info("Delete event for node", "node", klog.KObj(node))
	if err := sched.Cache.RemoveNode(logger, node); err != nil {
		utilruntime.HandleErrorWithLogger(logger, err, "Scheduler cache RemoveNode failed")
	}

Review comment (suggestion):
I wonder if new API that takes a start time will be a better API that will eliminate this class of errors

Code after:

	logger.V(4).Info("Update event for node", "node", klog.KObj(newNode))
	nodeInfo := sched.Cache.UpdateNode(logger, oldNode, newNode)
	events := framework.NodeSchedulingPropertiesChange(newNode, oldNode)

	// Save the time it takes to update the node in the cache.
	updatingDuration := metrics.SinceInSeconds(start)

	// Only requeue unschedulable pods if the node became more schedulable.
	for _, evt := range events {
		startMoving := time.Now()
		sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, evt, oldNode, newNode, preCheckForNode(logger, nodeInfo))
		movingDuration := metrics.SinceInSeconds(startMoving)

		metrics.EventHandlingLatency.WithLabelValues(evt.Label()).Observe(updatingDuration + movingDuration)
	}
}

func (sched *Scheduler) deleteNodeFromCache(obj interface{}) {
	evt := fwk.ClusterEvent{Resource: fwk.Node, ActionType: fwk.Delete}
	defer metrics.EventHandlingLatency.ObserveSince(time.Now(), evt.Label())()

	logger := sched.logger
	var node *v1.Node
	switch t := obj.(type) {
	case *v1.Node:
		node = t
	case cache.DeletedFinalStateUnknown:
		var ok bool
		node, ok = t.Obj.(*v1.Node)
		if !ok {
			utilruntime.HandleErrorWithLogger(logger, nil, "Cannot convert to *v1.Node", "obj", t.Obj)
			return
		}
	default:
		utilruntime.HandleErrorWithLogger(logger, nil, "Cannot convert to *v1.Node", "obj", t)
		return
	}

	sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, evt, node, nil, nil)

	logger.V(3).Info("Delete event for node", "node", klog.KObj(node))
	if err := sched.Cache.RemoveNode(logger, node); err != nil {
		utilruntime.HandleErrorWithLogger(logger, err, "Scheduler cache RemoveNode failed")
	}
}

func (sched *Scheduler) addPod(obj interface{}) {
	logger := sched.logger
	pod, ok := obj.(*v1.Pod)
	if !ok {