From 38d1a93660ed2d1d9773751749aa4f20bf0670e2 Mon Sep 17 00:00:00 2001 From: Thomas Hipp Date: Tue, 18 Feb 2025 14:25:21 +0100 Subject: [PATCH 1/4] grpc: Add external dependency to grpc trailer --- grpc/server.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/grpc/server.go b/grpc/server.go index 97d06ff4..762aeaac 100644 --- a/grpc/server.go +++ b/grpc/server.go @@ -88,6 +88,10 @@ func Server(ab AuthBackend, logger grpc_logging.Logger) *grpc.Server { start := time.Now() err := handler(srv, wrappedStream) + if err := addExternalDependencyToTrailer(ctx); err != nil { + log.Ctx(ctx).Warn().Err(err).Msg("unable to add external dependencies to trailer") + } + log.Ctx(ctx).Info().Str("method", info.FullMethod). Dur("duration", time.Since(start)). Str("type", "stream"). @@ -120,6 +124,10 @@ func Server(ab AuthBackend, logger grpc_logging.Logger) *grpc.Server { start := time.Now() resp, err = handler(ctx, req) + if err := addExternalDependencyToTrailer(ctx); err != nil { + log.Ctx(ctx).Warn().Err(err).Msg("unable to add external dependencies to trailer") + } + log.Ctx(ctx).Info().Str("method", info.FullMethod). Dur("duration", time.Since(start)). Str("type", "unary"). @@ -143,6 +151,19 @@ func Server(ab AuthBackend, logger grpc_logging.Logger) *grpc.Server { return myServer } +// addExternalDependencyToTrailer adds the external dependencies to the grpc trailer. +// This is used to track external dependencies which are updated during the request lifecycle. +func addExternalDependencyToTrailer(ctx context.Context) error { + edc := middleware.ExternalDependencyContextFromContext(ctx) + if edc == nil { + return nil + } + + md := metadata.Pairs(MetadataKeyExternalDependencies, edc.String()) + + return grpc.SetTrailer(ctx, md) +} + func prepareContext(ctx context.Context) (context.Context, metadata.MD) { md, _ := metadata.FromIncomingContext(ctx) logger := zlog.With().Logger() From c02f1022d729cd10568703a2e0b0b045c0718f0d Mon Sep 17 00:00:00 2001 From: Thomas Hipp Date: Tue, 18 Feb 2025 14:59:40 +0100 Subject: [PATCH 2/4] grpc: Add external dependencies to context from grpc metadata --- grpc/middleware.go | 20 ++++++++++++++++++++ grpc/middleware_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/grpc/middleware.go b/grpc/middleware.go index 04cea44e..3b9d25db 100644 --- a/grpc/middleware.go +++ b/grpc/middleware.go @@ -7,6 +7,7 @@ import ( "encoding/gob" "strings" + "github.com/pace/bricks/http/middleware" "github.com/pace/bricks/pkg/tracking/utm" "google.golang.org/grpc/metadata" ) @@ -36,3 +37,22 @@ func EncodeContextWithUTMData(parentCtx context.Context) context.Context { } return metadata.AppendToOutgoingContext(parentCtx, utmMetadataKey, w.String()) } + +// AddExternalDependencyMetadataToContext adds external dependencies to the context if they are present in the metadata. +func AddExternalDependencyMetadataToContext(ctx context.Context, md metadata.MD) context.Context { + // If there are no external dependencies in the metadata, we can return the context as is. + externalDependencies := md.Get(MetadataKeyExternalDependencies) + if len(externalDependencies) == 0 { + return ctx + } + + // If there are external dependencies in the metadata, we need to parse them and add them to the context. + edc := middleware.ExternalDependencyContextFromContext(ctx) + if edc == nil { + edc = &middleware.ExternalDependencyContext{} + } + + edc.Parse(externalDependencies[0]) + + return middleware.ContextWithExternalDependency(ctx, edc) +} diff --git a/grpc/middleware_test.go b/grpc/middleware_test.go index 474070bd..3cd6ccfc 100644 --- a/grpc/middleware_test.go +++ b/grpc/middleware_test.go @@ -6,6 +6,7 @@ import ( "context" "testing" + "github.com/pace/bricks/http/middleware" "github.com/pace/bricks/pkg/tracking/utm" "github.com/stretchr/testify/require" "google.golang.org/grpc/metadata" @@ -31,3 +32,29 @@ func TestEncodeContextWithUTMData(t *testing.T) { require.True(t, exists) require.Equal(t, data, utmData) } + +func TestAddExternalDependencyMetadataToContext(t *testing.T) { + md := metadata.New(map[string]string{ + MetadataKeyExternalDependencies: "dep1:1,dep2:2,dep3:3", + }) + ctx := context.Background() + ctx = AddExternalDependencyMetadataToContext(ctx, md) + edc := middleware.ExternalDependencyContextFromContext(ctx) + require.NotNil(t, edc) + require.Equal(t, "dep1:1,dep2:2,dep3:3", edc.String()) + + ctx = AddExternalDependencyMetadataToContext(ctx, metadata.New(map[string]string{ + MetadataKeyExternalDependencies: "dep4:4,dep5:5,dep6:6", + })) + edc = middleware.ExternalDependencyContextFromContext(ctx) + require.NotNil(t, edc) + require.Equal(t, "dep1:1,dep2:2,dep3:3,dep4:4,dep5:5,dep6:6", edc.String()) +} + +func TestAddExternalDependencyMetadataToContext_NoDependencies(t *testing.T) { + md := metadata.New(map[string]string{}) + ctx := context.Background() + ctx = AddExternalDependencyMetadataToContext(ctx, md) + edc := middleware.ExternalDependencyContextFromContext(ctx) + require.Nil(t, edc) +} From 9b799267a7fbb6aa78ec3ae20ba2ffc31cf8815f Mon Sep 17 00:00:00 2001 From: Thomas Hipp Date: Thu, 20 Feb 2025 17:11:22 +0100 Subject: [PATCH 3/4] grpc: Set max retries for client --- grpc/client.go | 1 + 1 file changed, 1 insertion(+) diff --git a/grpc/client.go b/grpc/client.go index 6a979fb5..20772cb2 100644 --- a/grpc/client.go +++ b/grpc/client.go @@ -36,6 +36,7 @@ func NewClient(addr string) (*grpc.ClientConn, error) { opts := []grpc_retry.CallOption{ grpc_retry.WithBackoff(grpc_retry.BackoffLinear(100 * time.Millisecond)), + grpc_retry.WithMax(10), } conn, err := grpc.NewClient(addr, From 4ab1bd3e6e6ae7c0a1f8cf57411c0d2401609b62 Mon Sep 17 00:00:00 2001 From: Thomas Hipp Date: Thu, 20 Feb 2025 17:24:39 +0100 Subject: [PATCH 4/4] gomod: Update dependencies --- go.mod | 12 ++++++------ go.sum | 29 ++++++++++++++--------------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 3f931b70..65ea9519 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.1 github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 - github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.2.0 + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0 github.com/jpillora/backoff v1.0.0 github.com/mattn/go-isatty v0.0.20 github.com/minio/minio-go/v7 v7.0.7 @@ -38,9 +38,9 @@ require ( github.com/uptrace/bun/dialect/pgdialect v1.2.9 github.com/uptrace/bun/driver/pgdriver v1.2.9 github.com/zenazn/goji v1.0.1 - golang.org/x/text v0.21.0 + golang.org/x/text v0.22.0 google.golang.org/grpc v1.67.1 - google.golang.org/protobuf v1.34.2 + google.golang.org/protobuf v1.36.4 ) require ( @@ -74,9 +74,9 @@ require ( github.com/yuin/gopher-lua v1.1.0 // indirect go.opentelemetry.io/otel v1.34.0 // indirect go.opentelemetry.io/otel/trace v1.34.0 // indirect - golang.org/x/crypto v0.32.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.29.0 // indirect + golang.org/x/crypto v0.33.0 // indirect + golang.org/x/net v0.35.0 // indirect + golang.org/x/sys v0.30.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index 7fdd9eb7..d8ad2c20 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,4 @@ bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= -cloud.google.com/go/compute v1.23.4 h1:EBT9Nw4q3zyE7G45Wvv3MzolIrCJEuHys5muLY0wvAw= cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= github.com/PuerkitoBio/rehttp v1.4.0 h1:rIN7A2s+O9fmHUM1vUcInvlHj9Ysql4hE+Y0wcl/xk8= @@ -79,8 +78,8 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA= github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.2.0 h1:kQ0NI7W1B3HwiN5gAYtY+XFItDPbLBwYRxAqbFTyDes= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.2.0/go.mod h1:zrT2dxOAjNFPRGjTUe2Xmb4q4YdUwVvQFV6xiCSf+z0= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0 h1:FbSCl+KggFl+Ocym490i/EyXF4lPgLoUtcSWquBM0Rs= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0/go.mod h1:qOchhhIlmRcqk/O9uCo/puJlyo07YINaIqdZfZG3Jkc= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -209,19 +208,19 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -235,14 +234,14 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -254,8 +253,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1: google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM= +google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=