|
@@ -106,6 +106,9 @@ type KeysAPI interface {
|
|
|
// Create is an alias for Set w/ PrevExist=false
|
|
// Create is an alias for Set w/ PrevExist=false
|
|
|
Create(ctx context.Context, key, value string) (*Response, error)
|
|
Create(ctx context.Context, key, value string) (*Response, error)
|
|
|
|
|
|
|
|
|
|
+ // CreateInOrder is used to atomically create in-order keys within the given directory.
|
|
|
|
|
+ CreateInOrder(ctx context.Context, dir, value string, opts *CreateInOrderOptions) (*Response, error)
|
|
|
|
|
+
|
|
|
// Update is an alias for Set w/ PrevExist=true
|
|
// Update is an alias for Set w/ PrevExist=true
|
|
|
Update(ctx context.Context, key, value string) (*Response, error)
|
|
Update(ctx context.Context, key, value string) (*Response, error)
|
|
|
|
|
|
|
@@ -133,6 +136,14 @@ type WatcherOptions struct {
|
|
|
Recursive bool
|
|
Recursive bool
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+type CreateInOrderOptions struct {
|
|
|
|
|
+ // TTL defines a period of time after-which the Node should
|
|
|
|
|
+ // expire and no longer exist. Values <= 0 are ignored. Given
|
|
|
|
|
+ // that the zero-value is ignored, TTL cannot be used to set
|
|
|
|
|
+ // a TTL of 0.
|
|
|
|
|
+ TTL time.Duration
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
type SetOptions struct {
|
|
type SetOptions struct {
|
|
|
// PrevValue specifies what the current value of the Node must
|
|
// PrevValue specifies what the current value of the Node must
|
|
|
// be in order for the Set operation to succeed.
|
|
// be in order for the Set operation to succeed.
|
|
@@ -294,6 +305,25 @@ func (k *httpKeysAPI) Create(ctx context.Context, key, val string) (*Response, e
|
|
|
return k.Set(ctx, key, val, &SetOptions{PrevExist: PrevNoExist})
|
|
return k.Set(ctx, key, val, &SetOptions{PrevExist: PrevNoExist})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (k *httpKeysAPI) CreateInOrder(ctx context.Context, dir, val string, opts *CreateInOrderOptions) (*Response, error) {
|
|
|
|
|
+ act := &createInOrderAction{
|
|
|
|
|
+ Prefix: k.prefix,
|
|
|
|
|
+ Dir: dir,
|
|
|
|
|
+ Value: val,
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if opts != nil {
|
|
|
|
|
+ act.TTL = opts.TTL
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ resp, body, err := k.client.Do(ctx, act)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return unmarshalHTTPResponse(resp.StatusCode, resp.Header, body)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
func (k *httpKeysAPI) Update(ctx context.Context, key, val string) (*Response, error) {
|
|
func (k *httpKeysAPI) Update(ctx context.Context, key, val string) (*Response, error) {
|
|
|
return k.Set(ctx, key, val, &SetOptions{PrevExist: PrevExist})
|
|
return k.Set(ctx, key, val, &SetOptions{PrevExist: PrevExist})
|
|
|
}
|
|
}
|
|
@@ -492,6 +522,28 @@ func (a *deleteAction) HTTPRequest(ep url.URL) *http.Request {
|
|
|
return req
|
|
return req
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+type createInOrderAction struct {
|
|
|
|
|
+ Prefix string
|
|
|
|
|
+ Dir string
|
|
|
|
|
+ Value string
|
|
|
|
|
+ TTL time.Duration
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (a *createInOrderAction) HTTPRequest(ep url.URL) *http.Request {
|
|
|
|
|
+ u := v2KeysURL(ep, a.Prefix, a.Dir)
|
|
|
|
|
+
|
|
|
|
|
+ form := url.Values{}
|
|
|
|
|
+ form.Add("value", a.Value)
|
|
|
|
|
+ if a.TTL > 0 {
|
|
|
|
|
+ form.Add("ttl", strconv.FormatUint(uint64(a.TTL.Seconds()), 10))
|
|
|
|
|
+ }
|
|
|
|
|
+ body := strings.NewReader(form.Encode())
|
|
|
|
|
+
|
|
|
|
|
+ req, _ := http.NewRequest("POST", u.String(), body)
|
|
|
|
|
+ req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
|
|
|
+ return req
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
func unmarshalHTTPResponse(code int, header http.Header, body []byte) (res *Response, err error) {
|
|
func unmarshalHTTPResponse(code int, header http.Header, body []byte) (res *Response, err error) {
|
|
|
switch code {
|
|
switch code {
|
|
|
case http.StatusOK, http.StatusCreated:
|
|
case http.StatusOK, http.StatusCreated:
|