如何使一个变量在 gRPC 服务器上的所有 gRPC 请求处理程序中都可用?

huangapple go评论83阅读模式
英文:

How to make a variable available to all gRPC request handlers on a gRPC server?

问题

你可以通过将变量添加到gRPC请求上下文中来实现在所有请求处理程序中使用它。在Run()函数中,你可以使用context.WithValue()函数将foo变量添加到gRPC服务器的上下文中。然后,在请求处理程序中,你可以使用ctx.Value()函数来获取该变量的值。

下面是修改后的代码示例:

func Run(...) ... {
    // this is variable I want to add to all my request handler's context
    foo := "bar"

    grpcServer := grpc.NewServer()
    grpc_health_v1.RegisterHealthServer(grpcServer, health.NewServer())
    pb.RegisterMyServer(grpcServer, newServer())
    signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT)

    go func() {
        if err := grpcServer.Serve(lis); err != nil {
            errChan <- err
        }
    }()

    return grpcServer, nil
}

func (s *myServer) Ping(
    ctx context.Context,
    pingRequest *pb.PingRequest,
) (*pb.PingResponse, error) {
    // 获取foo变量的值
    foo := ctx.Value("foo").(string)

    // 使用foo变量进行处理
    // ...

    return &pb.PingResponse{}, nil
}

Run()函数中,你可以使用context.WithValue()函数将foo变量添加到gRPC服务器的上下文中:

ctx := context.WithValue(context.Background(), "foo", foo)

然后,在请求处理程序中,你可以使用ctx.Value()函数来获取该变量的值:

foo := ctx.Value("foo").(string)

这样,你就可以在所有请求处理程序中使用foo变量了。

英文:

I'm starting my gRPC server like this:

func Run(...) ... {
    // this is variable I want to add to all my request handler&#39;s context
    foo := &quot;bar&quot;

	grpcServer := grpc.NewServer()
	grpc_health_v1.RegisterHealthServer(grpcServer, health.NewServer())
	pb.RegisterMyServer(grpcServer, newServer())
	signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT)

	go func() {
		if err := grpcServer.Serve(lis); err != nil {
			errChan &lt;- err
		}
	}()

	return grpcServer, nil
}

And here's an example of a handler for a "ping" request:

func (s *myServer) Ping(
	ctx context.Context,
	pingRequest *pb.PingRequest,
) (*pb.PingResponse, error) {
	return &amp;pb.PingResponse{}, nil
}

You can see in Run() that I have a variable foo that I would somehow like to be available to all my request handlers. This variable does not depend on the client's request in any way, it just needs to be available in the request handlers.

What is the best way to achieve this?

  • Use a singleton
  • Use a global
  • Somehow add it to the gRPC request contexts?

答案1

得分: 2

使用您的自定义实现来创建GRPC服务器。

type GrpcServer struct {
	Foo string
}

func (g *GrpcServer) Ping(ctx context.Context, pingRequest *pb.PingRequest) (*pb.PingResponse, error) {
	fmt.Println(g.Foo)
	return &pb.PingResponse{}, nil
}

并注册您的自定义实现到GRPC服务器。

func Run() {
	foo := "bar"

	grpcServer := grpc.NewServer()
	grpc_health_v1.RegisterHealthServer(grpcServer, health.NewServer())
	pb.RegisterMyServer(grpcServer, &GrpcServer{Foo: foo})
	signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT)

	go func() {
		if err := grpcServer.Serve(lis); err != nil {
			errChan <- err
		}
	}()

	return grpcServer, nil
}
英文:

Use your custom implementation to GRPC server.

type GrpcServer struct {
	Foo string
}

func (g *GrpcServer) Ping(ctx context.Context, pingRequest *pb.PingRequest, ) (*pb.PingResponse, error) {
	fmt.Println(g.Foo)
	return &amp;pb.PingResponse{}, nil
}

And register your custom implementation of grpc server.

func Run() {
	
	foo := &quot;bar&quot;

	grpcServer := grpc.NewServer()
	grpc_health_v1.RegisterHealthServer(grpcServer, health.NewServer())
	pb.RegisterMyServer(grpcServer, &amp;GrpcServer{Foo: foo})
	signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT)

	go func() {
		if err := grpcServer.Serve(lis); err != nil {
			errChan &lt;- err
		}
	}()

	return grpcServer, nil
}

huangapple
  • 本文由 发表于 2021年6月10日 17:24:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/67918370.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定