diff --git a/api/types/load_traffic.go b/api/types/load_traffic.go index 0d61661..0bba901 100644 --- a/api/types/load_traffic.go +++ b/api/types/load_traffic.go @@ -46,6 +46,10 @@ type LoadProfileSpec struct { ContentType ContentType `json:"contentType" yaml:"contentType"` // DisableHTTP2 means client will use HTTP/1.1 protocol if it's true. DisableHTTP2 bool `json:"disableHTTP2" yaml:"disableHTTP2"` + // MaxRetries makes the request use the given integer as a ceiling of + // retrying upon receiving "Retry-After" headers and 429 status-code + // in the response (<= 0 means no retry). + MaxRetries int `json:"maxRetries" yaml:"maxRetries"` // Requests defines the different kinds of requests with weights. // The executor should randomly pick by weight. Requests []*WeightedRequest diff --git a/cmd/kperf/commands/runner/runner.go b/cmd/kperf/commands/runner/runner.go index 5b4e73e..6a08dbb 100644 --- a/cmd/kperf/commands/runner/runner.go +++ b/cmd/kperf/commands/runner/runner.go @@ -72,6 +72,11 @@ var runCommand = cli.Command{ Name: "disable-http2", Usage: "Disable HTTP2 protocol", }, + cli.IntFlag{ + Name: "max-retries", + Usage: "Retry request after receiving 429 http code (<=0 means no retry)", + Value: 0, + }, cli.StringFlag{ Name: "result", Usage: "Path to the file which stores results", @@ -170,6 +175,9 @@ func loadConfig(cliCtx *cli.Context) (*types.LoadProfile, error) { if v := "disable-http2"; cliCtx.IsSet(v) { profileCfg.Spec.DisableHTTP2 = cliCtx.Bool(v) } + if v := "max-retries"; cliCtx.IsSet(v) { + profileCfg.Spec.MaxRetries = cliCtx.Int(v) + } if err := profileCfg.Validate(); err != nil { return nil, err diff --git a/request/random.go b/request/random.go index 8bd061f..b01202b 100644 --- a/request/random.go +++ b/request/random.go @@ -41,13 +41,13 @@ func NewWeightedRandomRequests(spec *types.LoadProfileSpec) (*WeightedRandomRequ var builder RESTRequestBuilder switch { case r.StaleList != nil: - builder = newRequestListBuilder(r.StaleList, "0") + builder = newRequestListBuilder(r.StaleList, "0", spec.MaxRetries) case r.QuorumList != nil: - builder = newRequestListBuilder(r.QuorumList, "") + builder = newRequestListBuilder(r.QuorumList, "", spec.MaxRetries) case r.StaleGet != nil: - builder = newRequestGetBuilder(r.StaleGet, "0") + builder = newRequestGetBuilder(r.StaleGet, "0", spec.MaxRetries) case r.QuorumGet != nil: - builder = newRequestGetBuilder(r.QuorumGet, "") + builder = newRequestGetBuilder(r.QuorumGet, "", spec.MaxRetries) default: return nil, fmt.Errorf("not implement for PUT yet") } @@ -130,9 +130,10 @@ type requestGetBuilder struct { namespace string name string resourceVersion string + maxRetries int } -func newRequestGetBuilder(src *types.RequestGet, resourceVersion string) *requestGetBuilder { +func newRequestGetBuilder(src *types.RequestGet, resourceVersion string, maxRetries int) *requestGetBuilder { return &requestGetBuilder{ version: schema.GroupVersion{ Group: src.Group, @@ -142,6 +143,7 @@ func newRequestGetBuilder(src *types.RequestGet, resourceVersion string) *reques namespace: src.Namespace, name: src.Name, resourceVersion: resourceVersion, + maxRetries: maxRetries, } } @@ -165,7 +167,7 @@ func (b *requestGetBuilder) Build(cli rest.Interface) (string, *rest.Request) { &metav1.GetOptions{ResourceVersion: b.resourceVersion}, scheme.ParameterCodec, schema.GroupVersion{Version: "v1"}, - ) + ).MaxRetries(b.maxRetries) } type requestListBuilder struct { @@ -175,9 +177,10 @@ type requestListBuilder struct { limit int64 labelSelector string resourceVersion string + maxRetries int } -func newRequestListBuilder(src *types.RequestList, resourceVersion string) *requestListBuilder { +func newRequestListBuilder(src *types.RequestList, resourceVersion string, maxRetries int) *requestListBuilder { return &requestListBuilder{ version: schema.GroupVersion{ Group: src.Group, @@ -188,6 +191,7 @@ func newRequestListBuilder(src *types.RequestList, resourceVersion string) *requ limit: int64(src.Limit), labelSelector: src.Selector, resourceVersion: resourceVersion, + maxRetries: maxRetries, } } @@ -215,5 +219,5 @@ func (b *requestListBuilder) Build(cli rest.Interface) (string, *rest.Request) { }, scheme.ParameterCodec, schema.GroupVersion{Version: "v1"}, - ) + ).MaxRetries(b.maxRetries) }