// Copy the reader to the response. The created WebSocket is closed after this // method completes. func (r *Reader) Copy(w http.ResponseWriter, req *http.Request) error { go func() { defer util.HandleCrash() websocket.Server{Handshake: r.handshake, Handler: r.handle}.ServeHTTP(w, req) }() return <-r.err }
// Run begins processing items, and will continue until a value is sent down stopCh. // It's an error to call Run more than once. // Run blocks; call via go. func (c *Controller) Run(stopCh <-chan struct{}) { defer util.HandleCrash() r := cache.NewReflector( c.config.ListerWatcher, c.config.ObjectType, c.config.Queue, c.config.FullResyncPeriod, ) c.reflectorMutex.Lock() c.reflector = r c.reflectorMutex.Unlock() r.RunUntil(stopCh) util.Until(c.processLoop, time.Second, stopCh) }
// getOrExpire retrieves the object from the timestampedEntry if and only if it hasn't // already expired. It kicks-off a go routine to delete expired objects from // the store and sets exists=false. func (c *ExpirationCache) getOrExpire(key string) (interface{}, bool) { timestampedItem, exists := c.getTimestampedEntry(key) if !exists { return nil, false } if c.expirationPolicy.IsExpired(timestampedItem) { glog.V(4).Infof("Entry %v: %+v has expired", key, timestampedItem.obj) // Since expiration happens lazily on read, don't hold up // the reader trying to acquire a write lock for the delete. // The next reader will retry the delete even if this one // fails; as long as we only return un-expired entries a // reader doesn't need to wait for the result of the delete. go func() { defer util.HandleCrash() c.cacheStorage.Delete(key) }() return nil, false } return timestampedItem.obj, true }