code: func (m *Manager) Update(interval time.Duration, files []string, externalLabels labels.Labels) error {
  	m.mtx.Lock()
  	defer m.mtx.Unlock()
  
  	groups, errs := m.LoadGroups(interval, externalLabels, files...)
  	if errs != nil {
  		for _, e := range errs {
  			level.Error(m.logger).Log("msg", "loading groups failed", "err", e)
  		}
  		return errors.New("error loading rules, previous rule set restored")
  	}
  	m.restored = true
  
  	var wg sync.WaitGroup
  
  	for _, newg := range groups {
  		wg.Add(1)
  
  		// If there is an old group with the same identifier, stop it and wait for
  		// it to finish the current iteration. Then copy it into the new group.
  		gn := groupKey(newg.name, newg.file)
  		oldg, ok := m.groups[gn]
  		delete(m.groups, gn)
  
  		go func(newg *Group) {
  			if ok {
  				oldg.stop()
  				newg.CopyState(oldg)
  			}
  			go func() {
  				// Wait with starting evaluation until the rule manager
  				// is told to run. This is necessary to avoid running
  				// queries against a bootstrapping storage.
  				<-m.block
  				newg.run(m.opts.Context)
  			}()
  			wg.Done()
  		}(newg)
  	}
  
  	// Stop remaining old groups.
  	for _, oldg := range m.groups {
  		oldg.stop()
  	}
  
  	wg.Wait()
  	m.groups = groups
  
  	return nil
  }
docs: // Update the rule manager's state as the config requires. If
  // loading the new rules failed the old rule set is restored.