mirror of
https://github.com/status-im/consul.git
synced 2025-01-09 13:26:07 +00:00
agent: Adding support for specifying LockDelay, defaults to 15 seconds.
This commit is contained in:
parent
e0abf2e92c
commit
00a107dfd9
@ -6,6 +6,17 @@ import (
|
||||
"github.com/hashicorp/consul/consul/structs"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// lockDelayMinThreshold is used to convert a numeric lock
|
||||
// delay value from nanoseconds to seconds if it is below this
|
||||
// threshold. Users often send a value like 5, which they assume
|
||||
// is seconds, but because Go uses nanosecond granularity, ends
|
||||
// up being very small. If we see a value below this threshold,
|
||||
// we multply by time.Second
|
||||
lockDelayMinThreshold = 1000
|
||||
)
|
||||
|
||||
// sessionCreateResponse is used to wrap the session ID
|
||||
@ -27,13 +38,14 @@ func (s *HTTPServer) SessionCreate(resp http.ResponseWriter, req *http.Request)
|
||||
Session: structs.Session{
|
||||
Node: s.agent.config.NodeName,
|
||||
Checks: []string{consul.SerfCheckID},
|
||||
LockDelay: 15 * time.Second,
|
||||
},
|
||||
}
|
||||
s.parseDC(req, &args.Datacenter)
|
||||
|
||||
// Handle optional request body
|
||||
if req.ContentLength > 0 {
|
||||
if err := decodeBody(req, &args.Session, nil); err != nil {
|
||||
if err := decodeBody(req, &args.Session, FixupLockDelay); err != nil {
|
||||
resp.WriteHeader(400)
|
||||
resp.Write([]byte(fmt.Sprintf("Request decode failed: %v", err)))
|
||||
return nil, nil
|
||||
@ -50,6 +62,45 @@ func (s *HTTPServer) SessionCreate(resp http.ResponseWriter, req *http.Request)
|
||||
return sessionCreateResponse{out}, nil
|
||||
}
|
||||
|
||||
// FixupLockDelay is used to handle parsing the JSON body to session/create
|
||||
// and properly parsing out the lock delay duration value.
|
||||
func FixupLockDelay(raw interface{}) error {
|
||||
rawMap, ok := raw.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
var key string
|
||||
for k, _ := range rawMap {
|
||||
if strings.ToLower(k) == "lockdelay" {
|
||||
key = k
|
||||
break
|
||||
}
|
||||
}
|
||||
if key != "" {
|
||||
val := rawMap[key]
|
||||
// Convert a string value into an integer
|
||||
if vStr, ok := val.(string); ok {
|
||||
dur, err := time.ParseDuration(vStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if dur < lockDelayMinThreshold {
|
||||
dur = dur * time.Second
|
||||
}
|
||||
rawMap[key] = dur
|
||||
}
|
||||
// Convert low value integers into seconds
|
||||
if vNum, ok := val.(float64); ok {
|
||||
dur := time.Duration(vNum)
|
||||
if dur < lockDelayMinThreshold {
|
||||
dur = dur * time.Second
|
||||
}
|
||||
rawMap[key] = dur
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SessionDestroy is used to destroy an existing session
|
||||
func (s *HTTPServer) SessionDestroy(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
args := structs.SessionRequest{
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestSessionCreate(t *testing.T) {
|
||||
@ -35,6 +36,7 @@ func TestSessionCreate(t *testing.T) {
|
||||
raw := map[string]interface{}{
|
||||
"Node": srv.agent.config.NodeName,
|
||||
"Checks": []string{consul.SerfCheckID, "consul"},
|
||||
"LockDelay": "20s",
|
||||
}
|
||||
enc.Encode(raw)
|
||||
|
||||
@ -52,10 +54,41 @@ func TestSessionCreate(t *testing.T) {
|
||||
if _, ok := obj.(sessionCreateResponse); !ok {
|
||||
t.Fatalf("should work")
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func TestFixupLockDelay(t *testing.T) {
|
||||
inp := map[string]interface{}{
|
||||
"lockdelay": float64(15),
|
||||
}
|
||||
if err := FixupLockDelay(inp); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if inp["lockdelay"] != 15*time.Second {
|
||||
t.Fatalf("bad: %v", inp)
|
||||
}
|
||||
|
||||
inp = map[string]interface{}{
|
||||
"lockDelay": float64(15 * time.Second),
|
||||
}
|
||||
if err := FixupLockDelay(inp); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if inp["lockDelay"] != 15*time.Second {
|
||||
t.Fatalf("bad: %v", inp)
|
||||
}
|
||||
|
||||
inp = map[string]interface{}{
|
||||
"LockDelay": "15s",
|
||||
}
|
||||
if err := FixupLockDelay(inp); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if inp["LockDelay"] != 15*time.Second {
|
||||
t.Fatalf("bad: %v", inp)
|
||||
}
|
||||
}
|
||||
|
||||
func makeTestSession(t *testing.T, srv *HTTPServer) string {
|
||||
req, err := http.NewRequest("PUT", "/v1/session/create", nil)
|
||||
if err != nil {
|
||||
|
Loading…
x
Reference in New Issue
Block a user