etcdserver/api/v2store/store.go
func (s *store) Update(nodePath string, newValue string, expireOpts TTLOptionSet) (*Event, error) {
	var err *v2error.Error

	s.worldLock.Lock()
	defer s.worldLock.Unlock()

	defer func() {
		if err == nil {
			s.Stats.Inc(UpdateSuccess)
			reportWriteSuccess(Update)
			return
		}

		s.Stats.Inc(UpdateFail)
		reportWriteFailure(Update)
	}()

	nodePath = path.Clean(path.Join("/", nodePath))
	// we do not allow the user to change "/"
	if s.readonlySet.Contains(nodePath) {
		return nil, v2error.NewError(v2error.EcodeRootROnly, "/", s.CurrentIndex)
	}

	currIndex, nextIndex := s.CurrentIndex, s.CurrentIndex+1

	n, err := s.internalGet(nodePath)
	if err != nil { // if the node does not exist, return error
		return nil, err
	}
	if n.IsDir() && len(newValue) != 0 {
		// if the node is a directory, we cannot update value to non-empty
		return nil, v2error.NewError(v2error.EcodeNotFile, nodePath, currIndex)
	}

	if expireOpts.Refresh {
		newValue = n.Value
	}

	e := newEvent(Update, nodePath, nextIndex, n.CreatedIndex)
	e.EtcdIndex = nextIndex
	e.PrevNode = n.Repr(false, false, s.clock)
	eNode := e.Node

	n.Write(newValue, nextIndex)

	if n.IsDir() {
		eNode.Dir = true
	} else {
		// copy the value for safety
		newValueCopy := newValue
		eNode.Value = &newValueCopy
	}

	// update ttl
	n.UpdateTTL(expireOpts.ExpireTime)

	eNode.Expiration, eNode.TTL = n.expirationAndTTL(s.clock)

	if !expireOpts.Refresh {
		s.WatcherHub.notify(e)
	} else {
		e.SetRefresh()
		s.WatcherHub.add(e)
	}

	s.CurrentIndex = nextIndex

	return e, nil
}
func (s *store) Update(nodePath string, newValue string, expireOpts TTLOptionSet) (*Event, error) {
	var err *v2error.Error

	s.worldLock.Lock()
	defer s.worldLock.Unlock()

	defer func() {
		if err == nil {
			s.Stats.Inc(UpdateSuccess)
			reportWriteSuccess(Update)
			return
		}

		s.Stats.Inc(UpdateFail)
		reportWriteFailure(Update)
	}()

	nodePath = path.Clean(path.Join("/", nodePath))
	// we do not allow the user to change "/"
	if s.readonlySet.Contains(nodePath) {
		return nil, v2error.NewError(v2error.EcodeRootROnly, "/", s.CurrentIndex)
	}

	currIndex, nextIndex := s.CurrentIndex, s.CurrentIndex+1

	n, err := s.internalGet(nodePath)
	if err != nil { // if the node does not exist, return error
		return nil, err
	}
	if n.IsDir() && len(newValue) != 0 {
		// if the node is a directory, we cannot update value to non-empty
		return nil, v2error.NewError(v2error.EcodeNotFile, nodePath, currIndex)
	}

	if expireOpts.Refresh {
		newValue = n.Value
	}

	e := newEvent(Update, nodePath, nextIndex, n.CreatedIndex)
	e.EtcdIndex = nextIndex
	e.PrevNode = n.Repr(false, false, s.clock)
	eNode := e.Node

	n.Write(newValue, nextIndex)

	if n.IsDir() {
		eNode.Dir = true
	} else {
		// copy the value for safety
		newValueCopy := newValue
		eNode.Value = &newValueCopy
	}

	// update ttl
	n.UpdateTTL(expireOpts.ExpireTime)

	eNode.Expiration, eNode.TTL = n.expirationAndTTL(s.clock)

	if !expireOpts.Refresh {
		s.WatcherHub.notify(e)
	} else {
		e.SetRefresh()
		s.WatcherHub.add(e)
	}

	s.CurrentIndex = nextIndex

	return e, nil
}
func ( s * store ) Update ( nodePath string , newValue string , expireOpts TTLOptionSet ) ( * Event , error ) { var err * v2error . Error s . worldLock . Lock ( ) defer s . worldLock . Unlock ( ) defer func ( ) { if err == nil { s . Stats . Inc ( UpdateSuccess ) reportWriteSuccess ( Update ) return } s . Stats . Inc ( UpdateFail ) reportWriteFailure ( Update ) } ( ) nodePath = path . Clean ( path . Join ( " " , nodePath ) ) // we do not allow the user to change "/" if s . readonlySet . Contains ( nodePath ) { return nil , v2error . NewError ( v2error . EcodeRootROnly , " " , s . CurrentIndex ) } currIndex , nextIndex := s . CurrentIndex , s . CurrentIndex + 1 n , err := s . internalGet ( nodePath ) if err != nil { // if the node does not exist, return error return nil , err } if n . IsDir ( ) && len ( newValue ) != 0 { // if the node is a directory, we cannot update value to non-empty return nil , v2error . NewError ( v2error . EcodeNotFile , nodePath , currIndex ) } if expireOpts . Refresh { newValue = n . Value } e := newEvent ( Update , nodePath , nextIndex , n . CreatedIndex ) e . EtcdIndex = nextIndex e . PrevNode = n . Repr ( false , false , s . clock ) eNode := e . Node n . Write ( newValue , nextIndex ) if n . IsDir ( ) { eNode . Dir = true } else { // copy the value for safety newValueCopy := newValue eNode . Value = & newValueCopy } // update ttl n . UpdateTTL ( expireOpts . ExpireTime ) eNode . Expiration , eNode . TTL = n . expirationAndTTL ( s . clock ) if ! expireOpts . Refresh { s . WatcherHub . notify ( e ) } else { e . SetRefresh ( ) s . WatcherHub . add ( e ) } s . CurrentIndex = nextIndex return e , nil }
// Update updates the value/ttl of the node.
// If the node is a file, the value and the ttl can be updated.
// If the node is a directory, only the ttl can be updated.
Update updates the value / ttl of the node . If the node is a file the value and the ttl can be updated . If the node is a directory only the ttl can be updated .