// 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 }
// 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 }