1

When a golang gRPC server calls a handler function, the ctx value handed is derived from a private top context created here, in the grpc transport layer:
/go/pkg/mod/google.golang.org/grpc@v1.27.0/internal/transport/http2_server.go:219

t := &http2Server{
        ctx:               context.Background(),
        done:              done,
        conn:              conn,
        remoteAddr:        conn.RemoteAddr()
         ...

Is there a reason why that context is not derived from a root context provided at the construction of the server?

Perhaps grpc.NewServer(opt ...ServerOption) could have a ctx variant grpc.NewServerCtx(ctx, ...ServerOption)?

That would give you the option for transmitting values you'd like all the contexts to contain.

  • 2
    You'd have to ask the authors. – Adrian Mar 06 '20 at 18:06
  • Looks to me that maybe this follows a pattern I'm not aware of. – Victor Dramba Mar 06 '20 at 18:08
  • 1
    It's not exported because all contexts should be passed explicitly; and it's not the root context for requests, it's used internally by the server; and it's in an `internal` package on an unexported type which you don't have access to. What would exporting it actually accomplish? – JimB Mar 06 '20 at 18:24
  • 1
    My question is not why is that context not exported but rather why is it not derived from a user provided one. So that you can have a root context for your entire application. – Victor Dramba Mar 06 '20 at 18:40
  • And this http2Server.ctx is indeed the root context from which request contexts are ultimately stemming from. – Victor Dramba Mar 06 '20 at 18:45
  • It sounds like you want to be able to stop the gRPC service & any currently running requests shoula be canceled - via this root context. If this is the case, you can [merge contexts](https://stackoverflow.com/a/58489004/1218512) to achieve this effect. – colm.anseo Mar 06 '20 at 19:35
  • @colminator, not really but similar. Our microservice apps typically create a root context that is used for all setup process. This context is populated with tools like logging, tracing and other values. We don't use it for cancelling. We ended up with a strategy similar to your merger, but it is a hack. If grpc.NewServer would accept a root context, this would be a much cleaner pattern. Why is that not provided? That's my question. – Victor Dramba Mar 06 '20 at 20:08
  • @VictorDramba: if that is your question, then the appropriate place to ask is with the go grpc project, not StackOverflow. – JimB Mar 07 '20 at 03:06

1 Answers1

0

I think it is a very good question. The answer is, because that package is not availiable for external calls, why should there be something exported, when nobody is allowed to use that package?

But why is it a private package?

Let's look at the path of your file:

/google.golang.org/grpc@v1.27.0/internal/transport/http2_server.go:219

The internal is the key here:

/google.golang.org/grpc@v1.27.0/internal/

everything inside that path is just for the package.

So for that code you are showing nobody from outside is able to use that package. So everything inside ther can be unexported.

apxp
  • 5,240
  • 4
  • 23
  • 43
  • 1
    I think the OP is questioning the _decision_ to make the context private/inaccessible, not the actual implementation that makes it private. – colm.anseo Mar 06 '20 at 19:40
  • At no place in my OP i'm talking about making the context public. Storage and flow of that context is indeed an implementation detail. My question is, why am I not given the option of specifying the root context at the construction of the server. This would be part of the library API, and a pretty common pattern as far as I understand. – Victor Dramba Mar 06 '20 at 20:14