go.temporal.io/server/common/rpc/grpc.go

137 LOC · 58 covered · 79 uncovered · 9 ranges · 76 concepts · 4 introducers · 16 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 package rpc
2
3 import (
4 "context"
5 "crypto/tls"
6 "net"
7 "time"
8
9 "go.temporal.io/server/common/headers"
10 "go.temporal.io/server/common/log"
11 "go.temporal.io/server/common/metrics"
12 "go.temporal.io/server/common/rpc/interceptor"
13 serviceerrors "go.temporal.io/server/common/serviceerror"
14 "google.golang.org/grpc"
15 "google.golang.org/grpc/backoff"
16 "google.golang.org/grpc/credentials"
17 "google.golang.org/grpc/credentials/insecure"
18 "google.golang.org/grpc/status"
19 )
20
21 const (
22 // DefaultServiceConfig is a default gRPC connection service config which enables DNS round robin between IPs.
23 // To use DNS resolver, a "dns:///" prefix should be applied to the hostPort.
24 // https://github.com/grpc/grpc/blob/master/doc/naming.md
25 DefaultServiceConfig = `{"loadBalancingConfig": [{"round_robin":{}}]}`
26
27 // MaxBackoffDelay is a maximum interval between reconnect attempts.
28 MaxBackoffDelay = 10 * time.Second
29
30 // MaxHTTPAPIRequestBytes is the maximum number of bytes an HTTP API request
31 // can have. This is currently set to the max gRPC request size.
32 MaxHTTPAPIRequestBytes = 4 * 1024 * 1024
33
34 // MaxNexusAPIRequestBodyBytes is the maximum number of bytes a Nexus HTTP API request can have. Because the body is
35 // read into a Payload object, this is currently set to the max Payload size. Content headers are transformed to
36 // Payload metadata and contribute to the Payload size as well. A separate limit is enforced on top of this.
37 MaxNexusAPIRequestBodyBytes = 2 * 1024 * 1024
38
39 // minConnectTimeout is the minimum amount of time we are willing to give a connection to complete.
40 minConnectTimeout = 20 * time.Second
41
42 // maxInternodeRecvPayloadSize indicates the internode max receive payload size.
43 maxInternodeRecvPayloadSize = 128 * 1024 * 1024 // 128 Mb
44 )
45
46 // Dial creates a client connection to the given target with default options.
47 // The hostName syntax is defined in
48 // https://github.com/grpc/grpc/blob/master/doc/naming.md.
49 // dns resolver is used by default
50 func Dial(
51 hostName string,
52 tlsConfig *tls.Config,
53 logger log.Logger,
54 metricsHandler metrics.Handler,
55 opts ...grpc.DialOption,
56 > ) (*grpc.ClientConn, error) { grpc.go ×4
57 > var grpcSecureOpt grpc.DialOption
58 > if tlsConfig == nil {
59 > grpcSecureOpt = grpc.WithTransportCredentials(insecure.NewCredentials()) fx.go ×44
60 > } else { grpc.go ×4
61 > grpcSecureOpt = grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)) rpc.go ×4
62 > }
63
64 // gRPC maintains connection pool inside grpc.ClientConn.
65 // This connection pool has auto reconnect feature.
66 // If connection goes down, gRPC will try to reconnect using exponential backoff strategy:
67 // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md.
68 // Default MaxDelay is 120 seconds which is too high.
69 > var cp = grpc.ConnectParams{ grpc.go ×4
70 > Backoff: backoff.DefaultConfig,
71 > MinConnectTimeout: minConnectTimeout,
72 > }
73 > cp.Backoff.MaxDelay = MaxBackoffDelay
74 >
75 > dtrace := newDialTracer(hostName, metricsHandler, logger)
76 >
77 > contextDialer := func(ctx context.Context, s string) (net.Conn, error) {
78 > // Keep the existing gRPC behavior by using OS defaults for TCP keepalive settings. grpc.go ×3
79 > // We are on Go 1.23+ and can use KeepAliveConfig directly instead of the old KeepAlive/Control hacks.
80 > dialer := &net.Dialer{
81 > KeepAliveConfig: net.KeepAliveConfig{
82 > Enable: true,
83 > },
84 > }
85 >
86 > var ndt *networkDialTrace
87 > ctx, ndt = dtrace.beginNetworkDial(ctx)
88 > conn, dialErr := dialer.DialContext(ctx, "tcp", s)
89 > dtrace.endNetworkDial(ndt, dialErr)
90 > return conn, dialErr
91 > }
92
93 > dialOptions := []grpc.DialOption{ grpc.go ×4
94 > grpcSecureOpt,
95 > grpc.WithContextDialer(contextDialer),
96 > grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(maxInternodeRecvPayloadSize)),
97 > grpc.WithChainUnaryInterceptor(
98 > headersInterceptor,
99 > metrics.NewClientMetricsTrailerPropagatorInterceptor(logger),
100 > errorInterceptor,
101 > ),
102 > grpc.WithChainStreamInterceptor(
103 > interceptor.StreamErrorInterceptor,
104 > ),
105 > grpc.WithDefaultServiceConfig(DefaultServiceConfig),
106 > grpc.WithDisableServiceConfig(),
107 > grpc.WithConnectParams(cp),
108 > }
109 > dialOptions = append(dialOptions, opts...)
110 >
111 > return grpc.NewClient(hostName, dialOptions...)
112 }
113
114 func errorInterceptor(
115 ctx context.Context,
116 method string,
117 req, reply any,
118 cc *grpc.ClientConn,
119 invoker grpc.UnaryInvoker,
120 opts ...grpc.CallOption,
121 > ) error { grpc.go ×3
122 > err := invoker(ctx, method, req, reply, cc, opts...)
123 > err = serviceerrors.FromStatus(status.Convert(err))
124 > return err
125 > }
126
127 func headersInterceptor(
128 ctx context.Context,
129 method string,
130 req, reply any,
131 cc *grpc.ClientConn,
132 invoker grpc.UnaryInvoker,
133 opts ...grpc.CallOption,
134 > ) error { grpc.go ×3
135 > ctx = headers.Propagate(ctx)
136 > return invoker(ctx, method, req, reply, cc, opts...)
137 > }