|
|
|
@ -15,21 +15,22 @@ import (
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type (
|
|
|
|
|
// ServerSpecifiedTimeoutConf defines specified timeout for gRPC method.
|
|
|
|
|
ServerSpecifiedTimeoutConf struct {
|
|
|
|
|
// MethodTimeoutConf defines specified timeout for gRPC method.
|
|
|
|
|
MethodTimeoutConf struct {
|
|
|
|
|
FullMethod string
|
|
|
|
|
Timeout time.Duration
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
specifiedTimeoutCache map[string]time.Duration
|
|
|
|
|
methodTimeouts map[string]time.Duration
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// UnaryTimeoutInterceptor returns a func that sets timeout to incoming unary requests.
|
|
|
|
|
func UnaryTimeoutInterceptor(timeout time.Duration, specifiedTimeouts ...ServerSpecifiedTimeoutConf) grpc.UnaryServerInterceptor {
|
|
|
|
|
cache := cacheSpecifiedTimeout(specifiedTimeouts)
|
|
|
|
|
func UnaryTimeoutInterceptor(timeout time.Duration,
|
|
|
|
|
methodTimeouts ...MethodTimeoutConf) grpc.UnaryServerInterceptor {
|
|
|
|
|
timeouts := buildMethodTimeouts(methodTimeouts)
|
|
|
|
|
return func(ctx context.Context, req any, info *grpc.UnaryServerInfo,
|
|
|
|
|
handler grpc.UnaryHandler) (any, error) {
|
|
|
|
|
t := getTimeoutByUnaryServerInfo(info, timeout, cache)
|
|
|
|
|
t := getTimeoutByUnaryServerInfo(info.FullMethod, timeouts, timeout)
|
|
|
|
|
ctx, cancel := context.WithTimeout(ctx, t)
|
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
|
@ -72,27 +73,22 @@ func UnaryTimeoutInterceptor(timeout time.Duration, specifiedTimeouts ...ServerS
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func cacheSpecifiedTimeout(specifiedTimeouts []ServerSpecifiedTimeoutConf) specifiedTimeoutCache {
|
|
|
|
|
cache := make(specifiedTimeoutCache, len(specifiedTimeouts))
|
|
|
|
|
for _, st := range specifiedTimeouts {
|
|
|
|
|
func buildMethodTimeouts(timeouts []MethodTimeoutConf) methodTimeouts {
|
|
|
|
|
mt := make(methodTimeouts, len(timeouts))
|
|
|
|
|
for _, st := range timeouts {
|
|
|
|
|
if st.FullMethod != "" {
|
|
|
|
|
cache[st.FullMethod] = st.Timeout
|
|
|
|
|
mt[st.FullMethod] = st.Timeout
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return cache
|
|
|
|
|
return mt
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getTimeoutByUnaryServerInfo(info *grpc.UnaryServerInfo, defaultTimeout time.Duration, specifiedTimeout specifiedTimeoutCache) time.Duration {
|
|
|
|
|
if ts, ok := info.Server.(TimeoutStrategy); ok {
|
|
|
|
|
return ts.GetTimeoutByFullMethod(info.FullMethod, defaultTimeout)
|
|
|
|
|
} else if v, ok := specifiedTimeout[info.FullMethod]; ok {
|
|
|
|
|
func getTimeoutByUnaryServerInfo(method string, timeouts methodTimeouts,
|
|
|
|
|
defaultTimeout time.Duration) time.Duration {
|
|
|
|
|
if v, ok := timeouts[method]; ok {
|
|
|
|
|
return v
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return defaultTimeout
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type TimeoutStrategy interface {
|
|
|
|
|
GetTimeoutByFullMethod(fullMethod string, defaultTimeout time.Duration) time.Duration
|
|
|
|
|
}
|
|
|
|
|