Example #1
0
// Put a value at "key"
func (s *Etcd) Put(key string, value []byte, opts *store.WriteOptions) error {

	// Default TTL = 0 means no expiration
	var ttl uint64
	if opts != nil && opts.TTL > 0 {
		ttl = uint64(opts.TTL.Seconds())
	}

	if _, err := s.client.Set(key, string(value), ttl); err != nil {
		if etcdError, ok := err.(*etcd.EtcdError); ok {

			// Not a directory
			if etcdError.ErrorCode == 104 {
				// Remove the last element (the actual key)
				// and create the full directory path
				err = s.createDirectory(store.GetDirectory(key))
				if err != nil {
					return err
				}

				// Now that the directory is created, set the key
				if _, err := s.client.Set(key, string(value), ttl); err != nil {
					return err
				}
			}
		}
		return err
	}
	return nil
}
Example #2
0
// AtomicPut put a value at "key" if the key has not been
// modified in the meantime, throws an error if this is the case
func (s *Etcd) AtomicPut(key string, value []byte, previous *store.KVPair, options *store.WriteOptions) (bool, *store.KVPair, error) {

	var meta *etcd.Response
	var err error
	if previous != nil {
		meta, err = s.client.CompareAndSwap(store.Normalize(key), string(value), 0, "", previous.LastIndex)
	} else {
		// Interpret previous == nil as Atomic Create
		meta, err = s.client.Create(store.Normalize(key), string(value), 0)
		if etcdError, ok := err.(*etcd.EtcdError); ok {

			// Directory doesn't exist.
			if etcdError.ErrorCode == 104 {
				// Remove the last element (the actual key)
				// and create the full directory path
				err = s.createDirectory(store.GetDirectory(key))
				if err != nil {
					return false, nil, err
				}

				// Now that the directory is created, create the key
				if _, err := s.client.Create(key, string(value), 0); err != nil {
					return false, nil, err
				}
			}
		}
	}
	if err != nil {
		if etcdError, ok := err.(*etcd.EtcdError); ok {
			// Compare Failed
			if etcdError.ErrorCode == 101 {
				return false, nil, store.ErrKeyModified
			}
		}
		return false, nil, err
	}

	updated := &store.KVPair{
		Key:       key,
		Value:     value,
		LastIndex: meta.Node.ModifiedIndex,
	}

	return true, updated, nil
}