code: func (p *ChangePoller) Run(c context.Context) {
  	if p.Period <= 0 {
  		return
  	}
  
  	for {
  		// If our Context has been canceled, terminate.
  		select {
  		case <-c.Done():
  			log.WithError(c.Err()).Warningf(c, "Terminating poll loop: context has been cancelled.")
  			return
  		default:
  			// Continue
  		}
  
  		log.Fields{
  			"timeout": p.Period,
  		}.Debugf(c, "Entering change check poll loop...")
  		if tr := clock.Sleep(c, p.Period); tr.Incomplete() {
  			log.WithError(tr.Err).Debugf(c, "Context cancelled, shutting down change poller.")
  			return
  		}
  
  		log.Infof(c, "Change check timeout triggered, checking configuration...")
  		lastHash := p.ContentHash
  		switch err := p.Refresh(c); {
  		case err != nil:
  			log.WithError(err).Errorf(c, "Failed to refresh config.")
  
  		case lastHash != p.ContentHash:
  			log.Fields{
  				"originalHash": lastHash,
  				"newHash":      p.ContentHash,
  			}.Warningf(c, "Configuration content hash has changed.")
  			if p.OnChange != nil {
  				p.OnChange()
  			}
  
  		default:
  			log.Fields{
  				"currentHash": lastHash,
  			}.Debugf(c, "Content hash matches.")
  		}
  	}
  }
docs: // Run starts polling for changes. It will stop when the Context is cancelled.