diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 6eb6a3222c3..630967784c7 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -1896,17 +1896,19 @@ func (kl *Kubelet) syncLoop(updates <-chan PodUpdate, handler SyncHandler) { } housekeepingTimestamp = time.Now() } - kl.syncLoopIteration(updates, handler) + if !kl.syncLoopIteration(updates, handler) { + break + } } } -func (kl *Kubelet) syncLoopIteration(updates <-chan PodUpdate, handler SyncHandler) { +func (kl *Kubelet) syncLoopIteration(updates <-chan PodUpdate, handler SyncHandler) bool { kl.syncLoopMonitor.Store(time.Now()) select { - case u, ok := <-updates: - if !ok { + case u, open := <-updates: + if !open { glog.Errorf("Update channel is closed. Exiting the sync loop.") - return + return false } switch u.Op { case ADD: @@ -1928,6 +1930,7 @@ func (kl *Kubelet) syncLoopIteration(updates <-chan PodUpdate, handler SyncHandl handler.HandlePodSyncs(kl.podManager.GetPods()) } kl.syncLoopMonitor.Store(time.Now()) + return true } func (kl *Kubelet) dispatchWork(pod *api.Pod, syncType SyncPodType, mirrorPod *api.Pod, start time.Time) { diff --git a/pkg/kubelet/kubelet_test.go b/pkg/kubelet/kubelet_test.go index 816fed19923..b1cd78c7bc0 100644 --- a/pkg/kubelet/kubelet_test.go +++ b/pkg/kubelet/kubelet_test.go @@ -329,6 +329,26 @@ func TestSyncLoopTimeUpdate(t *testing.T) { } } +func TestSyncLoopAbort(t *testing.T) { + testKubelet := newTestKubelet(t) + testKubelet.fakeCadvisor.On("MachineInfo").Return(&cadvisorApi.MachineInfo{}, nil) + kubelet := testKubelet.kubelet + kubelet.lastTimestampRuntimeUp = time.Now() + kubelet.networkConfigured = true + + ch := make(chan PodUpdate) + close(ch) + + // sanity check (also prevent this test from hanging in the next step) + ok := kubelet.syncLoopIteration(ch, kubelet) + if ok { + t.Fatalf("expected syncLoopIteration to return !ok since update chan was closed") + } + + // this should terminate immediately; if it hangs then the syncLoopIteration isn't aborting properly + kubelet.syncLoop(ch, kubelet) +} + func TestSyncPodsStartPod(t *testing.T) { testKubelet := newTestKubelet(t) testKubelet.fakeCadvisor.On("MachineInfo").Return(&cadvisorApi.MachineInfo{}, nil)