Skip to content

Commit 2976854

Browse files
committed
comment
Signed-off-by: Kenny Leung <kleung@chainguard.dev>
1 parent ac3cca1 commit 2976854

File tree

3 files changed

+46
-34
lines changed

3 files changed

+46
-34
lines changed

pkg/metrics/server.go

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"log"
1111
"net/http"
1212
"net/http/pprof"
13+
"sync"
1314
"time"
1415

1516
"github.com/chainguard-dev/clog"
@@ -25,7 +26,26 @@ import (
2526
"google.golang.org/grpc"
2627
)
2728

28-
var serverMetrics *grpc_prometheus.ServerMetrics
29+
type initStuff struct {
30+
serverMetrics *grpc_prometheus.ServerMetrics
31+
}
32+
33+
var (
34+
state = sync.OnceValue(func() initStuff {
35+
init := initStuff{}
36+
37+
init.serverMetrics = grpc_prometheus.NewServerMetrics(
38+
grpc_prometheus.WithServerHandlingTimeHistogram(
39+
grpc_prometheus.WithHistogramBuckets(
40+
[]float64{0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30, 60, 120, 300, 600, 1200, 2400, 3666},
41+
),
42+
),
43+
)
44+
prometheus.MustRegister(init.serverMetrics)
45+
46+
return init
47+
})
48+
)
2949

3050
// Fractions >= 1 will always sample. Fractions < 0 are treated as zero. To
3151
// respect the parent trace's `SampledFlag`, the `TraceIDRatioBased` sampler
@@ -65,15 +85,7 @@ func SetupTracer(ctx context.Context) func() {
6585
}
6686

6787
func RegisterListenAndServe(server *grpc.Server, listenAddr string, enablePprof bool) {
68-
serverMetrics = grpc_prometheus.NewServerMetrics(
69-
grpc_prometheus.WithServerHandlingTimeHistogram(
70-
grpc_prometheus.WithHistogramBuckets(
71-
[]float64{0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30, 60, 120, 300, 600, 1200, 2400, 3666},
72-
),
73-
),
74-
)
75-
prometheus.MustRegister(serverMetrics)
76-
serverMetrics.InitializeMetrics(server)
88+
state().serverMetrics.InitializeMetrics(server)
7789

7890
go func(addr string) {
7991
mux := http.NewServeMux()
@@ -109,9 +121,9 @@ func RegisterListenAndServe(server *grpc.Server, listenAddr string, enablePprof
109121
}
110122

111123
func UnaryServerInterceptor() grpc.UnaryServerInterceptor {
112-
return serverMetrics.UnaryServerInterceptor()
124+
return state().serverMetrics.UnaryServerInterceptor()
113125
}
114126

115127
func StreamServerInterceptor() grpc.StreamServerInterceptor {
116-
return serverMetrics.StreamServerInterceptor()
128+
return state().serverMetrics.StreamServerInterceptor()
117129
}

pkg/options/options.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import (
1919

2020
"chainguard.dev/go-grpc-kit/pkg/trace"
2121
"github.com/chainguard-dev/clog"
22+
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus"
2223
grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/retry"
23-
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
2424
"github.com/kelseyhightower/envconfig"
2525
"github.com/prometheus/client_golang/prometheus"
2626
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
@@ -37,18 +37,17 @@ type envStruct struct {
3737
GrpcClientMaxRetry uint `envconfig:"GRPC_CLIENT_MAX_RETRY" default:"0"`
3838
}
3939

40-
var (
41-
envOnce sync.Once
42-
40+
type initStuff struct {
4341
env envStruct
4442
clientMetrics *grpc_prometheus.ClientMetrics
45-
)
43+
}
44+
45+
var (
46+
state = sync.OnceValue(func() initStuff {
47+
init := initStuff{}
4648

47-
// Parse these lazily, to allow clients to set their own in their main() or init().
48-
func getEnv() *envStruct {
49-
envOnce.Do(func() {
5049
logger := clog.FromContext(context.Background())
51-
if err := envconfig.Process("", &env); err != nil {
50+
if err := envconfig.Process("", &init.env); err != nil {
5251
logger.Warn("Failed to process environment variables", "error", err)
5352
}
5453

@@ -58,21 +57,22 @@ func getEnv() *envStruct {
5857

5958
cmOpts := []grpc_prometheus.ClientMetricsOption{}
6059

61-
if env.EnableClientHandlingTimeHistogram {
60+
if init.env.EnableClientHandlingTimeHistogram {
6261
cmOpts = append(cmOpts, grpc_prometheus.WithClientHandlingTimeHistogram(hopt))
6362
}
64-
if env.EnableClientStreamReceiveTimeHistogram {
63+
if init.env.EnableClientStreamReceiveTimeHistogram {
6564
cmOpts = append(cmOpts, grpc_prometheus.WithClientStreamRecvHistogram(hopt))
6665
}
67-
if env.EnableClientStreamSendTimeHistogram {
66+
if init.env.EnableClientStreamSendTimeHistogram {
6867
cmOpts = append(cmOpts, grpc_prometheus.WithClientStreamSendHistogram(hopt))
6968
}
7069

71-
clientMetrics = grpc_prometheus.NewClientMetrics(cmOpts...)
72-
prometheus.MustRegister(clientMetrics)
70+
init.clientMetrics = grpc_prometheus.NewClientMetrics(cmOpts...)
71+
prometheus.MustRegister(init.clientMetrics)
72+
73+
return init
7374
})
74-
return &env
75-
}
75+
)
7676

7777
// ListenerForTest is to support bufnet in our testing.
7878
var ListenerForTest DialableListener
@@ -132,14 +132,14 @@ func ClientOptions() []option.ClientOption {
132132
func GRPCDialOptions() []grpc.DialOption {
133133
retryOpts := []grpc_retry.CallOption{
134134
grpc_retry.WithBackoff(grpc_retry.BackoffExponential(100 * time.Millisecond)),
135-
grpc_retry.WithMax(getEnv().GrpcClientMaxRetry),
135+
grpc_retry.WithMax(state().env.GrpcClientMaxRetry),
136136
}
137137

138138
return []grpc.DialOption{
139139
grpc.WithStatsHandler(otelgrpc.NewClientHandler()),
140140
grpc.WithStatsHandler(trace.PreserveTraceParentHandler),
141-
grpc.WithChainUnaryInterceptor(clientMetrics.UnaryClientInterceptor(), grpc_retry.UnaryClientInterceptor(retryOpts...)),
142-
grpc.WithChainStreamInterceptor(clientMetrics.StreamClientInterceptor(), grpc_retry.StreamClientInterceptor(retryOpts...)),
141+
grpc.WithChainUnaryInterceptor(state().clientMetrics.UnaryClientInterceptor(), grpc_retry.UnaryClientInterceptor(retryOpts...)),
142+
grpc.WithChainStreamInterceptor(state().clientMetrics.StreamClientInterceptor(), grpc_retry.StreamClientInterceptor(retryOpts...)),
143143
}
144144
}
145145

pkg/options/options_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,21 @@ func TestGetEnv(t *testing.T) {
1717
old := os.Getenv("GRPC_CLIENT_MAX_RETRY")
1818
defer os.Setenv("GRPC_CLIENT_MAX_RETRY", old)
1919

20-
want := &envStruct{
20+
want := envStruct{
2121
EnableClientHandlingTimeHistogram: true,
2222
EnableClientStreamReceiveTimeHistogram: true,
2323
EnableClientStreamSendTimeHistogram: true,
2424
GrpcClientMaxRetry: 42,
2525
}
2626
t.Run("can change env right before usage", func(t *testing.T) {
2727
os.Setenv("GRPC_CLIENT_MAX_RETRY", strconv.Itoa(int(want.GrpcClientMaxRetry)))
28-
if diff := cmp.Diff(want, getEnv()); diff != "" {
28+
if diff := cmp.Diff(want, state().env); diff != "" {
2929
t.Errorf("getEnv() -want,+got: %s", diff)
3030
}
3131
})
3232
t.Run("but cannot change after usage", func(t *testing.T) {
3333
os.Setenv("GRPC_CLIENT_MAX_RETRY", strconv.Itoa(int(want.GrpcClientMaxRetry+10)))
34-
if diff := cmp.Diff(want, getEnv()); diff != "" {
34+
if diff := cmp.Diff(want, state().env); diff != "" {
3535
t.Errorf("getEnv() -want,+got: %s", diff)
3636
}
3737
})

0 commit comments

Comments
 (0)