code: func (d *CachedDiscoveryClient) ServerGroups() (*metav1.APIGroupList, error) {
  	filename := filepath.Join(d.cacheDirectory, "servergroups.json")
  	cachedBytes, err := d.getCachedFile(filename)
  	// don't fail on errors, we either don't have a file or won't be able to run the cached check. Either way we can fallback.
  	if err == nil {
  		cachedGroups := &metav1.APIGroupList{}
  		if err := runtime.DecodeInto(scheme.Codecs.UniversalDecoder(), cachedBytes, cachedGroups); err == nil {
  			klog.V(10).Infof("returning cached discovery info from %v", filename)
  			return cachedGroups, nil
  		}
  	}
  
  	liveGroups, err := d.delegate.ServerGroups()
  	if err != nil {
  		klog.V(3).Infof("skipped caching discovery info due to %v", err)
  		return liveGroups, err
  	}
  	if liveGroups == nil || len(liveGroups.Groups) == 0 {
  		klog.V(3).Infof("skipped caching discovery info, no groups found")
  		return liveGroups, err
  	}
  
  	if err := d.writeCachedFile(filename, liveGroups); err != nil {
  		klog.V(1).Infof("failed to write cache to %v due to %v", filename, err)
  	}
  
  	return liveGroups, nil
  }
docs: // ServerGroups returns the supported groups, with information like supported versions and the
  // preferred version.