code: func (c *Cache) Get(key Key, data ...interface{}) (interface{}, error) {
  	keyStr := key.String()
  
  	f, ok := c.m.Load(keyStr)
  	if ok {
  		v, err := f.(future).Get()
  		if err != nil {
  			return nil, err
  		}
  		return c.value(v, first(data))
  	}
  
  	// The key wasn't found. Attempt to add one.
  	newFuture := futurevalue.New(
  		func() (interface{}, error) {
  			if closed := atomic.LoadInt32(&c.closed); closed == 1 {
  				return nil, errors.Errorf("%s - cache is closed", c.name)
  			}
  			return c.initializer(key, first(data))
  		},
  	)
  
  	f, loaded := c.m.LoadOrStore(keyStr, newFuture)
  	if loaded {
  		// Another thread has added the key before us. Return the value.
  		v, err := f.(future).Get()
  		if err != nil {
  			return nil, err
  		}
  		return c.value(v, first(data))
  	}
  
  	// We added the key. It must be initialized.
  	value, err := newFuture.Initialize()
  	if err != nil {
  		// Failed. Delete the key.
  		logger.Debugf("%s - Failed to initialize key [%s]: %s. Deleting key.", c.name, keyStr, err)
  		c.m.Delete(keyStr)
  		return nil, err
  	}
  	return c.value(value, first(data))
  }
docs: // Get returns the value for the given key. If the
  // key doesn't exist then the initializer is invoked
  // to create the value, and the key is inserted. If the
  // initializer returns an error then the key is removed
  // from the cache.