This repository was archived by the owner on Dec 30, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclient_timeouts.go
More file actions
69 lines (54 loc) · 1.56 KB
/
client_timeouts.go
File metadata and controls
69 lines (54 loc) · 1.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package grpcinterceptors
import (
"context"
"time"
"google.golang.org/grpc"
)
type TimeoutCallOption struct {
grpc.EmptyCallOption
forcedTimeout time.Duration
}
func WithForcedTimeout(forceTimeout time.Duration) TimeoutCallOption {
return TimeoutCallOption{forcedTimeout: forceTimeout} //nolint:exhaustruct
}
func getForcedTimeout(callOptions []grpc.CallOption) (time.Duration, bool) {
for _, opt := range callOptions {
if co, ok := opt.(TimeoutCallOption); ok {
return co.forcedTimeout, true
}
}
return 0, false
}
func UnaryTimeoutInterceptor(t time.Duration) grpc.UnaryClientInterceptor {
return func(
ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn,
invoker grpc.UnaryInvoker, opts ...grpc.CallOption,
) error {
timeout := t
if v, ok := getForcedTimeout(opts); ok {
timeout = v
}
if timeout <= 0 {
return invoker(ctx, method, req, reply, cc, opts...)
}
ctx, cancel := context.WithTimeout(ctx, timeout)
defer cancel()
return invoker(ctx, method, req, reply, cc, opts...)
}
}
func StreamTimeoutInterceptor(t time.Duration) grpc.StreamClientInterceptor {
return func(
ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string,
streamer grpc.Streamer, opts ...grpc.CallOption,
) (grpc.ClientStream, error) {
timeout := t
if v, ok := getForcedTimeout(opts); ok {
timeout = v
}
if timeout <= 0 {
return streamer(ctx, desc, cc, method, opts...)
}
ctx, _ = context.WithTimeout(ctx, timeout) //nolint:govet
return streamer(ctx, desc, cc, method, opts...)
}
}