Skip to content

Commit

Permalink
Implemented consul ttl functionality via sessions.
Browse files Browse the repository at this point in the history
  • Loading branch information
ashcrow committed Jun 13, 2015
1 parent fabdbf7 commit 689cf0c
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 5 deletions.
36 changes: 33 additions & 3 deletions consul.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package consuloretcd
// Consul specific implementation.

import (
"bytes"
"encoding/base64"
"encoding/json"
"errors"
"io/ioutil"
"net/http"
"net/url"
"strconv"
"strings"
)
Expand All @@ -24,15 +26,29 @@ type Consul struct {
Config
}

type Session struct {
TTL string `json:"TTL"`
Behavior string `json:"Behavior"`
}

// Makes the URI from the Consul struct
// Returns the full URI as a string
func (c Consul) makeURI(name string, opts KeyOptions) string {
url := c.Endpoint + ":" + strconv.Itoa(c.Port) + "/v1/kv/" + name
if opts.CSession != "" {
url = url + "?acquire=" + opts.CSession
}
return url
}

// makeParams creates a url.Values instance based off the KeyOptions
func (c Consul) makeParams(opts KeyOptions) url.Values {
v := url.Values{}
// TODO(ashcrow): This is a hack to avoid colliding with int:0. Fix it.
if opts.CASet != "" {
url = url + "?cas=" + opts.CASet
v.Set("cas", opts.CASet)
}
return url
return v
}

func (c Consul) checkAndReturn(resp *http.Response, kv KeyValue) (KeyValue, error) {
Expand Down Expand Up @@ -75,7 +91,7 @@ func (c Consul) GetKey(name string, opts KeyOptions) (KeyValue, error) {
kv := KeyValue{
Name: name,
Exists: false}
resp, err := c.Client.Get(c.makeURI(name, opts))
resp, err := c.Client.Get(c.makeURI(name, opts) + "?" + c.makeParams(opts).Encode())
if err != nil {
kv.Error = 1

Expand All @@ -93,6 +109,20 @@ func (c Consul) PutKey(name string, value string, opts KeyOptions) (KeyValue, er
kv := KeyValue{
Name: name,
Exists: false}
// TODO(ashcrow): We should probably allow 0 in the future
if opts.TTL != 0 {
// This means we need a session created as it controls the TTL
// TODO(ashcrow): error checking through here
ep := c.Endpoint + ":" + strconv.Itoa(c.Port) + "/v1/session/create"
jd, _ := json.Marshal(Session{TTL: strconv.Itoa(opts.TTL) + "s", Behavior: "delete"})
sess_req, _ := http.NewRequest("PUT", ep, bytes.NewReader(jd))
sess_resp, _ := c.Client.Do(sess_req)
defer sess_resp.Body.Close()
body, _ := ioutil.ReadAll(sess_resp.Body)
var result map[string]string
json.Unmarshal(body, &result)
opts.CSession = result["ID"]
}
req, _ := http.NewRequest("PUT", c.makeURI(name, opts), strings.NewReader(value))
resp, err := c.Client.Do(req)
if err != nil {
Expand Down
5 changes: 3 additions & 2 deletions shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ type Config struct {

// KeyOptions defines extra options when CRUDing keys.
type KeyOptions struct {
CASet string // Optional index that the key must be before modification
TTL int // A key's time to live
CASet string // Optional index that the key must be before modification
TTL int // A key's time to live
CSession string // Consul session. Only used with Consul.
}

// Returns a new KeyValueStore client based on the name
Expand Down

0 comments on commit 689cf0c

Please sign in to comment.