// watchLoop loops forever looking for new events. If an error occurs it will close the channel and return. func (eventSource *eventsSourceImpl) watchLoop(eventClient kubeclient.EventInterface, eventsChan chan<- eventsUpdate, errorChan chan<- error) { defer close(eventsChan) defer close(errorChan) events, err := eventClient.List(kubelabels.Everything(), kubefields.Everything()) if err != nil { glog.Errorf("Failed to load events: %v", err) errorChan <- err return } resourceVersion := events.ResourceVersion eventsChan <- eventsUpdate{events: events} if err := eventSource.storeEventsInCache(events); err != nil { glog.Errorf("failed to store events in cache: %v", err) errorChan <- err return } watcher, err := eventClient.Watch(kubelabels.Everything(), kubefields.Everything(), resourceVersion) if err != nil { glog.Errorf("Failed to start watch for new events: %v", err) errorChan <- err return } defer watcher.Stop() watchChannel := watcher.ResultChan() for { watchUpdate, ok := <-watchChannel if !ok { err := errors.New("watchLoop channel closed") errorChan <- err return } if watchUpdate.Type == kubewatch.Error { if status, ok := watchUpdate.Object.(*kubeapiunv.Status); ok { err := fmt.Errorf("Error during watch: %#v", status) errorChan <- err return } err := fmt.Errorf("Received unexpected error: %#v", watchUpdate.Object) errorChan <- err return } if event, ok := watchUpdate.Object.(*kubeapi.Event); ok { switch watchUpdate.Type { case kubewatch.Added, kubewatch.Modified: eList := &kubeapi.EventList{Items: []kubeapi.Event{*event}} eventsChan <- eventsUpdate{eList} if err := eventSource.storeEventsInCache(eList); err != nil { glog.Errorf("failed to store events in cache: %v", err) errorChan <- err return } case kubewatch.Deleted: // Deleted events are silently ignored default: err := fmt.Errorf("Unknown watchUpdate.Type: %#v", watchUpdate.Type) errorChan <- err return } resourceVersion = event.ResourceVersion continue } } }