@@ -14,6 +14,7 @@ import (
14
14
"net"
15
15
"os"
16
16
"strings"
17
+ "sync"
17
18
"time"
18
19
19
20
"cloud.google.com/go/compute/metadata"
@@ -27,6 +28,7 @@ import (
27
28
grpcgoogle "google.golang.org/grpc/credentials/google"
28
29
grpcinsecure "google.golang.org/grpc/credentials/insecure"
29
30
"google.golang.org/grpc/credentials/oauth"
31
+ "google.golang.org/grpc/stats"
30
32
31
33
// Install grpclb, which is required for direct path.
32
34
_ "google.golang.org/grpc/balancer/grpclb"
@@ -47,6 +49,26 @@ var logRateLimiter = rate.Sometimes{Interval: 1 * time.Second}
47
49
// Assign to var for unit test replacement
48
50
var dialContext = grpc .DialContext
49
51
52
+ // otelStatsHandler is a singleton otelgrpc.clientHandler to be used across
53
+ // all dial connections to avoid the memory leak documented in
54
+ // https://github.com/open-telemetry/opentelemetry-go-contrib/issues/4226
55
+ //
56
+ // TODO: If 4226 has been fixed in opentelemetry-go-contrib, replace this
57
+ // singleton with inline usage for simplicity.
58
+ var (
59
+ initOtelStatsHandlerOnce sync.Once
60
+ otelStatsHandler stats.Handler
61
+ )
62
+
63
+ // otelGRPCStatsHandler returns singleton otelStatsHandler for reuse across all
64
+ // dial connections.
65
+ func otelGRPCStatsHandler () stats.Handler {
66
+ initOtelStatsHandlerOnce .Do (func () {
67
+ otelStatsHandler = otelgrpc .NewClientHandler ()
68
+ })
69
+ return otelStatsHandler
70
+ }
71
+
50
72
// Dial returns a GRPC connection for use communicating with a Google cloud
51
73
// service, configured with the given ClientOptions.
52
74
func Dial (ctx context.Context , opts ... option.ClientOption ) (* grpc.ClientConn , error ) {
@@ -219,7 +241,7 @@ func addOpenTelemetryStatsHandler(opts []grpc.DialOption, settings *internal.Dia
219
241
if settings .TelemetryDisabled {
220
242
return opts
221
243
}
222
- return append (opts , grpc .WithStatsHandler (otelgrpc . NewClientHandler ()))
244
+ return append (opts , grpc .WithStatsHandler (otelGRPCStatsHandler ()))
223
245
}
224
246
225
247
// grpcTokenSource supplies PerRPCCredentials from an oauth.TokenSource.
0 commit comments