balancer: support injection of per-call metadata from LB policies#5853
Conversation
|
@dfawley : Based on our offline discussion, I've made changes to merge metadata from LB policies with existing call metadata instead of overwriting existing one. PTAL. Thanks. |
dfawley
left a comment
There was a problem hiding this comment.
LGTM modulo this one potential concern.
| // in a form passable to AppendToOutgoingContext(). | ||
| md, _ := metadata.FromOutgoingContext(ctx) | ||
| md = metadata.Join(md, a.pickResult.Metatada) | ||
| ctx = metadata.NewOutgoingContext(a.ctx, md) |
There was a problem hiding this comment.
Should this not update a.ctx in place instead? I'm a bit worried if we ever use it again later, it will be the wrong one.
There was a problem hiding this comment.
clientStream.ctxis the RPC's context (from what I can see, it is used directly and not derived from it)csAttempt.ctxis derived from the above context, and is used in the following placesgetTransport(): is passed toPick()- sending/receiving messages and when the attempt is closed, the context is passed to stats handler methods
I feel that by not modifying the csAttempt's context and instead deriving a new one (with metadata added by the LB policy) to be passed to NewStream(), we can ensure that we don't have any surprises when the attempt is retried. If we modify the csAttempt's context and the attempt is retried, and we call Pick() with the modified context, the LB policy's metadata might show up multiple times in there.
There was a problem hiding this comment.
Each attempt creates a new csAttempt, so that should not be a concern. Technically the attempt is not what's retried, but the RPC (clientStream).
There was a problem hiding this comment.
Each attempt creates a new csAttempt, so that should not be a concern.
Oh yes, that's right.
I'm a bit worried if we ever use it again later, it will be the wrong one.
When will we ever use it again? From what I see, the context is used in getTransport() and while invoking stats handler methods. Even if we add few usages for this context, why would it be helpful to pass the extra metadata added by the LB policy?
I'm not opposed to updating the attempt's context in place with metadata from the LB policy. But, I thought it was safer to derive one from it and pass it to NewStream and continue using the existing one for everything else, since that will minimize the effect of this change.
There was a problem hiding this comment.
I'm not sure we ever will use it again. But if ClientStream.Context() doesn't contain the true outgoing metadata, then that could potentially be considered a bug.
There was a problem hiding this comment.
clientStream.Context() returns the context from the underlying transport stream.
Line 701 in e53d28f
And we use the modified context (with all outgoing metadata) when creating the transport stream. So, it looks like we are good here too.
There was a problem hiding this comment.
Honestly it's still feeling wrong to not update the attempt's context when the metadata is updated by the LB policy. Unless there's a strong reason not to do this, then I'd rather do it and be safe vs. sorry. The concerns about it affecting subsequent attempts are a misunderstanding of the design of attempts (everything in an attempt should be local to that one attempt), and not a good reason to not update in place.
dfawley
left a comment
There was a problem hiding this comment.
LGTM (modulo a todo comment suggestion), thanks!
| // TODO: Make it possible to retrieve key value pairs from metadata.MD | ||
| // in a form passable to AppendToOutgoingContext(). |
There was a problem hiding this comment.
Maybe add to this sentence: ..., or create a version of AppendToOutgoingContext that accepts a metadata.MD. ?
Summary of changes:
balancer.PickResult. LB policies can use this to inject per-call arbitrary metadata.RELEASE NOTES: