MM-8607 Add ability to turn off non-critical services when under load (#13212)

* MM-8607: add ability to turn off non-critical services under load

* server busy invalid param unit tests

* MM-8607: rename server busy endpoints

* MM-8607: handle case where App not initialized

* MM-8607: additional unit test cases per feedback.

* MM-8607: use decorator to check isbusy when adding endpoint route

* MM-8607: rename endpoints, use struct for json

* Update api4/system.go

Fix misspelled log output

Co-Authored-By: Saturnino Abril <saturnino.abril@gmail.com>

* MM-8607: fix i18n order; max seconds for server busy expiry
Этот коммит содержится в:
Doug Lauder
2019-11-27 20:41:09 -05:00
коммит произвёл Joram Wilander
родитель 3cb3d874b8
Коммит 5abbe50258
21 изменённых файлов: 445 добавлений и 9 удалений

Просмотреть файл

@@ -420,6 +420,10 @@ func (c *Client4) GetRedirectLocationRoute() string {
return fmt.Sprintf("/redirect_location")
}
func (c *Client4) GetServerBusyRoute() string {
return "/server_busy"
}
func (c *Client4) GetUserTermsOfServiceRoute(userId string) string {
return c.GetUserRoute(userId) + "/terms_of_service"
}
@@ -4622,6 +4626,41 @@ func (c *Client4) GetRedirectLocation(urlParam, etag string) (string, *Response)
return MapFromJson(r.Body)["location"], BuildResponse(r)
}
// SetServerBusy will mark the server as busy, which disables non-critical services for `secs` seconds.
func (c *Client4) SetServerBusy(secs int) (bool, *Response) {
url := fmt.Sprintf("%s?seconds=%d", c.GetServerBusyRoute(), secs)
r, err := c.DoApiPost(url, "")
if err != nil {
return false, BuildErrorResponse(r, err)
}
defer closeBody(r)
return CheckStatusOK(r), BuildResponse(r)
}
// ClearServerBusy will mark the server as not busy.
func (c *Client4) ClearServerBusy() (bool, *Response) {
r, err := c.DoApiPost(c.GetServerBusyRoute()+"/clear", "")
if err != nil {
return false, BuildErrorResponse(r, err)
}
defer closeBody(r)
return CheckStatusOK(r), BuildResponse(r)
}
// GetServerBusyExpires returns the time when a server marked busy
// will automatically have the flag cleared.
func (c *Client4) GetServerBusyExpires() (*time.Time, *Response) {
r, err := c.DoApiGet(c.GetServerBusyRoute(), "")
if err != nil {
return nil, BuildErrorResponse(r, err)
}
defer closeBody(r)
sbs := ServerBusyStateFromJson(r.Body)
expires := time.Unix(sbs.Expires, 0)
return &expires, BuildResponse(r)
}
// RegisterTermsOfServiceAction saves action performed by a user against a specific terms of service.
func (c *Client4) RegisterTermsOfServiceAction(userId, termsOfServiceId string, accepted bool) (*bool, *Response) {
url := c.GetUserTermsOfServiceRoute(userId)

Просмотреть файл

@@ -50,3 +50,20 @@ type SystemECDSAKey struct {
Y *big.Int `json:"y"`
D *big.Int `json:"d,omitempty"`
}
type ServerBusyState struct {
Busy bool `json:"busy"`
Expires int64 `json:"expires"`
Expires_ts string `json:"expires_ts,omitempty"`
}
func (sbs *ServerBusyState) ToJson() string {
b, _ := json.Marshal(sbs)
return string(b)
}
func ServerBusyStateFromJson(r io.Reader) *ServerBusyState {
var sbs *ServerBusyState
json.NewDecoder(r).Decode(&sbs)
return sbs
}

Просмотреть файл

@@ -6,6 +6,7 @@ package model
import (
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
)
@@ -17,3 +18,13 @@ func TestSystemJson(t *testing.T) {
require.Equal(t, "test", result.Name, "ids do not match")
}
func TestServerBusyJson(t *testing.T) {
now := time.Now()
sbs := ServerBusyState{Busy: true, Expires: now.Unix()}
json := sbs.ToJson()
result := ServerBusyStateFromJson(strings.NewReader(json))
require.Equal(t, sbs.Busy, result.Busy, "busy state does not match")
require.Equal(t, sbs.Expires, result.Expires, "expiry does not match")
}

Просмотреть файл

@@ -207,7 +207,7 @@ func MapToJson(objmap map[string]string) string {
return string(b)
}
// MapToJson converts a map to a json string
// MapBoolToJson converts a map to a json string
func MapBoolToJson(objmap map[string]bool) string {
b, _ := json.Marshal(objmap)
return string(b)