I don't have time to setup a node environment at the moment.
Ylbam
ok
will give it a try on Linux, might be a Windows specific bug
not crashing on linux
ejona
Ylbam: One of our node devs didn't know why you'd see that behavior.
Ylbam
It crashes on win7, will try on win 10.
rmichela joined the channel
rmichela
@ejona Do you have a sec to talk about the plan for HTTP2 pseudo headers?
rmichela_ joined the channel
rmichela has quit
MXfive joined the channel
rmichela joined the channel
rmichela_ has quit
jud^ joined the channel
ejona
rmichela: Sorry, just saw your message. Do you mean what we'll do with :status?
rmichela
i'm particularly interested in :authority as it pertains to the HandlerRegistry API
also all pseudo headers in general
ejona
Ah, grpc/grpc-java#2704
rmichela
yes
ejona
We don't want to expose pseudo headers in Metadata. But Authority became a first-class thing.
:path is already a first-class thing.
So that only really leaves :status.
We'd like to remove it, but it isn't clear how to expose it. So we're just in a holding pattern with it.
We=me
rmichela
my understanding of why you don't want to expose all pseudo headers directly is that doing so would tie uses of gRPC to the specifics of http/2
ejona
I haven't looked at your PR deeply, but I saw the title and was happy to see it.
Yeah. We also have an API issue where we don't want Metadata Keys to have colons in them.
If you read the JavaDocs, it says that you can't use colons. But the implementation lets you, some of the time.
rmichela
i should look at how :path is being exposed above the transport layer
ejona
Whoa. We weren't using the lookupMethod with authority. Huh. Yeah. That's an oversight.
rmichela
yeah. it was never implemented
ejona
path == methodName (modulo leading /)
rmichela
the netty transport does a great job of sealing away all the pseudo headers from the higher layers
ejona
Okay. Then your change is probably best served by modifying streamCreated to also include authority as another argument.
(as I'm looking at the code)
(Even though the streamCreated is in an interface, it's an internal interface. We are okay with breaking it)
rmichela
using the stream's Attributes was a bit of a stretch, but i didn't want to modify any existing interfaces
ejona
Yeah. I think you did something quite reasonable without knowing more about how we do things. It isn't very invasive.
But I'm okay with the invasive change.
Oh.
rmichela
what do you think of Carl's comment "This is going to add extra allocation and AsciiString conversion in the serving path, where there was none before. Almost no users need this data. This would slow down all servers for the sake of proxies."
ejona
There's another option.
ServerStream could eventually get an authority() method. Maybe do that now.
I think that concern can be addressed a couple ways.
1) caching the last authority String and reusing it. It'll almost always be the same
2) future HPACK improvements where we cache results in the HPACK table.
I'd honestly be fine with doing neither of those today, but we are focusing enough of performance at this point that it can make sense to avoid some of the cost.
#2 is a bit much for now. But Carl could maybe be okay with saying we'll fix it when the HPACK caching is available.
rmichela
there could also be an optional flag on NettyServerBuilder that turns this functionality on
in the transparent proxy use case i'm experimenting with, the authority can change with every request
ejona
I think we'd be fine with the performance hit if it was changing every time, because that is a rarer case and you are probably fine with the minor performance difference.
So in the "I don't want to argue with people" sense, I'd probably just do #1 for when the authority doesn't change.
That should be really easy. Like 2-3 lines.
If it turns out to be hard, then we could re-evaluate. But if it is easy, that's what I would suggest.
rmichela
cache the authority string in the netty transport?
ejona
Yeah.
Err...
In the NettyServerHandler
Err... looking...
rmichela
perhaps i'm missing something, but how would i know if the authority string has changed without incurring the cost of decoding the authority string?
ejona
The authority string is already decoded, but it is in the form of an AsciiString. You can simply compare the old AsciiString to the new AsciiString.
Instead of adding a new argument to streamCreated(), I'd suggest adding a ServerStream.authority() method. And then call that method from ServerImpl.
You can make the change to Netty first and we can do some initial review. But you'd also need to add the authority() method to in-process transport.
Probably not too hard in terms of lines of code, but in-process may be scary initially.
rmichela looks at code
rmichela
is there a better point for me to branch off of than the commit that starts 1.2.0?
ejona
Anywhere on master is good.
That branch point was pretty recent, so it's fine.
rmichela
any place with stable unit tests?
i'm seeing a few failed tests when i build the latest master
ejona
Really? Which ones?
Huh. There is more flakiness or something.
rmichela
integration netty tests
like io.grpc.testing.integration.Http2NettyLocalChannelTest > unimplementedMethod FAILED
So that would mean passing the authority to the "new InProcessTransport"
rmichela
which is preferred when authority is absent, null, or empty string?
ejona
Eh. Probably doesn't matter much at this point. I'd say null.
|Pixel|
"less ressources" ? :)
ejona
Will more obviously break someone that uses it :)
|Pixel|: It requires 4 characters instead of two :-)
|Pixel|
I meant run-time ressources ? :D
rmichela
empty string is less likely to break consumers expecting a string, and Metadata has Metadata.EMPTY instead of null
what language level is gRPC? java 1.8?
sourceCompatibility = 1.6 :(
@ejona do you have a google-preferred, 1.6 compatible alternative to ConcurrentHashMap that supports computeIfAbsent()?
i'm trying to keep a map of AsciiString->String to avoid converting authority AsciiStrings that have already been seen by the NettyServerHandler
MXfive has quit
ejona
rmichela: the Netty handlers are thread-unsafe. They only execute from one thread at a time. Also, I think everyone would be very fine if it only cached the last authority.
The equivalent is to use ConcurrentHashMap.get() before putIfAbsent to avoid calculating unnecessarily. You may do slightly more computation, but it would still perform reasonably.