我正在try 编写一个一元拦截器来向传入请求添加请求ID:
func RequestIDInterceptor(ctx context.Context, req interface{},
info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (val interface{}, err error) {
newCtx := ctx
newCtx = createAndSetMetadata(newCtx, metadata.FromIncomingContext, metadata.NewIncomingContext)
newCtx = createAndSetMetadata(newCtx, metadata.FromOutgoingContext, metadata.NewOutgoingContext)
md, ok := metadata.FromOutgoingContext(newCtx)
fmt.Printf("After update. Metadata: %v, Found: %t\n", md, ok)
return handler(newCtx, req)
}
func createAndSetMetadata(ctx context.Context, getter func(context.Context) (metadata.MD, bool),
setter func(context.Context, metadata.MD) context.Context) context.Context {
meta, ok := getter(ctx)
fmt.Printf("Found? %t, Metadata: %v\n", ok, meta)
if !ok {
meta = metadata.New(map[string]string{})
ctx = setter(ctx, meta)
}
meta.Set("X-Request-Id", "TEST_REQUEST_ID")
fmt.Printf("Metadata: %v\n", meta)
return ctx
}
当请求不包括元数据(RequestIDInterceptor(context.Background(), nil, nil, handler)
)时,此代码按预期工作,但如果上下文包括元数据,则不会填充ID.基本上,输出如下所示:
WITHOUT METADATA
Found? false, Metadata: map[]
Metadata: map[x-request-id:[TEST_REQUEST_ID]]
Found? false, Metadata: map[]
Metadata: map[x-request-id:[TEST_REQUEST_ID]]
After update. Metadata: map[x-request-id:[TEST_REQUEST_ID]], Found: true
WITH METADATA
Found? true, Metadata: map[]
Metadata: map[x-request-id:[TEST_REQUEST_ID]]
Found? true, Metadata: map[]
Metadata: map[x-request-id:[TEST_REQUEST_ID]]
After update. Metadata: map[], Found: true
据我所知,发生这种情况的原因可能是metadata.MD
是通过值传递的,而不是通过引用传递的,所以当createAndSetMetadata
返回时,更新将被丢弃.我如何修复此代码?