feat: support customizing timeout for specific route (#1203)
* feat: support customizing timeout for specific route * test: add more tests
This commit is contained in:
@@ -120,7 +120,7 @@ func (ng *engine) bindRoute(fr featuredRoutes, router httpx.Router, metrics *sta
|
|||||||
handler.MaxConns(ng.conf.MaxConns),
|
handler.MaxConns(ng.conf.MaxConns),
|
||||||
handler.BreakerHandler(route.Method, route.Path, metrics),
|
handler.BreakerHandler(route.Method, route.Path, metrics),
|
||||||
handler.SheddingHandler(ng.getShedder(fr.priority), metrics),
|
handler.SheddingHandler(ng.getShedder(fr.priority), metrics),
|
||||||
handler.TimeoutHandler(time.Duration(ng.conf.Timeout)*time.Millisecond),
|
handler.TimeoutHandler(ng.checkedTimeout(fr.timeout)),
|
||||||
handler.RecoverHandler,
|
handler.RecoverHandler,
|
||||||
handler.MetricHandler(metrics),
|
handler.MetricHandler(metrics),
|
||||||
handler.MaxBytesHandler(ng.conf.MaxBytes),
|
handler.MaxBytesHandler(ng.conf.MaxBytes),
|
||||||
@@ -148,6 +148,14 @@ func (ng *engine) bindRoutes(router httpx.Router) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ng *engine) checkedTimeout(timeout time.Duration) time.Duration {
|
||||||
|
if timeout > 0 {
|
||||||
|
return timeout
|
||||||
|
}
|
||||||
|
|
||||||
|
return time.Duration(ng.conf.Timeout) * time.Millisecond
|
||||||
|
}
|
||||||
|
|
||||||
func (ng *engine) createMetrics() *stat.Metrics {
|
func (ng *engine) createMetrics() *stat.Metrics {
|
||||||
var metrics *stat.Metrics
|
var metrics *stat.Metrics
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/tal-tech/go-zero/core/conf"
|
"github.com/tal-tech/go-zero/core/conf"
|
||||||
@@ -154,6 +155,41 @@ Verbose: true
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEngine_checkedTimeout(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
timeout time.Duration
|
||||||
|
expect time.Duration
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "not set",
|
||||||
|
expect: time.Second,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "less",
|
||||||
|
timeout: time.Millisecond * 500,
|
||||||
|
expect: time.Millisecond * 500,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "equal",
|
||||||
|
timeout: time.Second,
|
||||||
|
expect: time.Second,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "more",
|
||||||
|
timeout: time.Millisecond * 1500,
|
||||||
|
expect: time.Millisecond * 1500,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
ng := newEngine(RestConf{
|
||||||
|
Timeout: 1000,
|
||||||
|
})
|
||||||
|
for _, test := range tests {
|
||||||
|
assert.Equal(t, test.expect, ng.checkedTimeout(test.timeout))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type mockedRouter struct{}
|
type mockedRouter struct{}
|
||||||
|
|
||||||
func (m mockedRouter) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
|
func (m mockedRouter) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/tal-tech/go-zero/core/logx"
|
"github.com/tal-tech/go-zero/core/logx"
|
||||||
"github.com/tal-tech/go-zero/rest/handler"
|
"github.com/tal-tech/go-zero/rest/handler"
|
||||||
@@ -204,6 +205,13 @@ func WithSignature(signature SignatureConf) RouteOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithTimeout returns a RouteOption to set timeout with given value.
|
||||||
|
func WithTimeout(timeout time.Duration) RouteOption {
|
||||||
|
return func(r *featuredRoutes) {
|
||||||
|
r.timeout = timeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithTLSConfig returns a RunOption that with given tls config.
|
// WithTLSConfig returns a RunOption that with given tls config.
|
||||||
func WithTLSConfig(cfg *tls.Config) RunOption {
|
func WithTLSConfig(cfg *tls.Config) RunOption {
|
||||||
return func(srv *Server) {
|
return func(srv *Server) {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/tal-tech/go-zero/core/conf"
|
"github.com/tal-tech/go-zero/core/conf"
|
||||||
@@ -238,6 +239,12 @@ func TestWithPriority(t *testing.T) {
|
|||||||
assert.True(t, fr.priority)
|
assert.True(t, fr.priority)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWithTimeout(t *testing.T) {
|
||||||
|
var fr featuredRoutes
|
||||||
|
WithTimeout(time.Hour)(&fr)
|
||||||
|
assert.Equal(t, time.Hour, fr.timeout)
|
||||||
|
}
|
||||||
|
|
||||||
func TestWithTLSConfig(t *testing.T) {
|
func TestWithTLSConfig(t *testing.T) {
|
||||||
const configYaml = `
|
const configYaml = `
|
||||||
Name: foo
|
Name: foo
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package rest
|
package rest
|
||||||
|
|
||||||
import "net/http"
|
import (
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// Middleware defines the middleware method.
|
// Middleware defines the middleware method.
|
||||||
@@ -28,6 +31,7 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
featuredRoutes struct {
|
featuredRoutes struct {
|
||||||
|
timeout time.Duration
|
||||||
priority bool
|
priority bool
|
||||||
jwt jwtSetting
|
jwt jwtSetting
|
||||||
signature signatureSetting
|
signature signatureSetting
|
||||||
|
|||||||
Reference in New Issue
Block a user