code: func StorageWithCacher(capacity int) generic.StorageDecorator {
  	return func(
  		storageConfig *storagebackend.Config,
  		resourcePrefix string,
  		keyFunc func(obj runtime.Object) (string, error),
  		newFunc func() runtime.Object,
  		newListFunc func() runtime.Object,
  		getAttrsFunc storage.AttrFunc,
  		triggerFunc storage.TriggerPublisherFunc) (storage.Interface, factory.DestroyFunc) {
  
  		s, d := generic.NewRawStorage(storageConfig)
  		if capacity <= 0 {
  			klog.V(5).Infof("Storage caching is disabled for %T", newFunc())
  			return s, d
  		}
  		if klog.V(5) {
  			klog.Infof("Storage caching is enabled for %T with capacity %v", newFunc(), capacity)
  		}
  
  		// TODO: we would change this later to make storage always have cacher and hide low level KV layer inside.
  		// Currently it has two layers of same storage interface -- cacher and low level kv.
  		cacherConfig := cacherstorage.Config{
  			CacheCapacity:        capacity,
  			Storage:              s,
  			Versioner:            etcdstorage.APIObjectVersioner{},
  			ResourcePrefix:       resourcePrefix,
  			KeyFunc:              keyFunc,
  			NewFunc:              newFunc,
  			NewListFunc:          newListFunc,
  			GetAttrsFunc:         getAttrsFunc,
  			TriggerPublisherFunc: triggerFunc,
  			Codec:                storageConfig.Codec,
  		}
  		cacher := cacherstorage.NewCacherFromConfig(cacherConfig)
  		destroyFunc := func() {
  			cacher.Stop()
  			d()
  		}
  
  		// TODO : Remove RegisterStorageCleanup below when PR
  		// https://github.com/kubernetes/kubernetes/pull/50690
  		// merges as that shuts down storage properly
  		RegisterStorageCleanup(destroyFunc)
  
  		return cacher, destroyFunc
  	}
  }
docs: // Creates a cacher based given storageConfig.