Coder Social home page Coder Social logo

Comments (70)

tv42 avatar tv42 commented on July 1, 2024

I just realized the grpc tls alpn is just HTTP/2 drafts, not a separate protocol. Scratch that plan; the splitting of grpc vs other needs to happen more per-{request|stream|something}.

from grpc-go.

stapelberg avatar stapelberg commented on July 1, 2024

I’d be interested in this as well.

from grpc-go.

acasajus avatar acasajus commented on July 1, 2024

Since there's no grpc/grpc-experiments#152 Can there be a failover stream handler? If the grpc server cannot process the stream (the service/method doesn't exist for instance) we could have another handler that devs can define to process it.

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

Yup, I think adding some additional handlers for non-grpc content is the way to go just like what we have done for google internal rpc framework. I will raise it to design discussion and get back to you once we have a decision.

from grpc-go.

acasajus avatar acasajus commented on July 1, 2024

From grpc/grpc-experiments#152: There's a mandatory content type for grpc. So streams that do not have it can be served by the default http handler.

from grpc-go.

acasajus avatar acasajus commented on July 1, 2024

Any news on this? Should we go ahead and make a PR?

from grpc-go.

xiang90 avatar xiang90 commented on July 1, 2024

I am also interested in this one.

/cc @xiang90 @yichengq

from grpc-go.

xiang90 avatar xiang90 commented on July 1, 2024

@iamqizhao Have you had the discussion yet? Any decision? Anything I can help to make this happen?

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

I think this is good to have. But I do not see a compelling demand to have
it now given a lot of other stuffs I am working on. So it is on my radar
but a low priority item. I will be more than happy to take a PR from you
guys.

On Wed, Apr 22, 2015 at 10:53 AM, Xiang Li [email protected] wrote:

@iamqizhao https://github.com/iamqizhao Have you had the discussion
yet? Any decision? Anything I can help to make this happen?


Reply to this email directly or view it on GitHub
#75 (comment).

from grpc-go.

xiang90 avatar xiang90 commented on July 1, 2024

@iamqizhao I can work on it.

Motivation:

  1. currently etcd and a few other my side projects have a http1 endpoint as it API.
  2. I want to support GRPC in the next few releases without adding a new port or break compatibility.

So ideally, grpc can forward http1 requests to my old handlers. But can you give me some direction to do that? I can start to explore and hopefully have a pr for it.

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

On Wed, Apr 22, 2015 at 11:16 AM, Xiang Li [email protected] wrote:

@iamqizhao https://github.com/iamqizhao I can work on it.

Motivation:

  1. currently etcd and a few other my side projects have a http1
    endpoint as it API.
  2. I want to support GRPC in the next few releases without adding a
    new port or break compatibility.

So ideally, grpc can forward http1 requests to my old handlers. But can
you give me some direction to do that? I can start to explore and hopefully
have a pr for it.

grpc-go uses bradfitz/http2 package to write & read http2 frames. I suspect
the framer.ReadFrame will error out if it receives a http1 request (need
look into the code or check with brad). If it is the case, it is not
trivial to implement this feature without some change to http2 package...

You can probably check https://github.com/gengo/grpc-gateway to see if
there is alternative to your problem.


Reply to this email directly or view it on GitHub
#75 (comment).

from grpc-go.

xiang90 avatar xiang90 commented on July 1, 2024

@iamqizhao

It seems @bradfitz's http2 server supports both http1 and http2 at the same time. Here is the related code

https://github.com/bradfitz/http2/blob/91f80303028022bc2034c277126b405a2257d990/server.go#L185-L192

Are we able to do the similar thing?

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

On Wed, Apr 22, 2015 at 4:04 PM, Xiang Li [email protected] wrote:

@iamqizhao https://github.com/iamqizhao

It seems @bradfitz https://github.com/bradfitz's http2 server supports
both http1 and http2 at the same time. Here is the related code

https://github.com/bradfitz/http2/blob/91f80303028022bc2034c277126b405a2257d990/server.go#L185-L192

Yep, the idea is to push the divergence stage (http1 or http2) before there
is any real traffic. It uses the usage NPN/ALPN to decide whether
http.Server creates a http2 ServerConn and dispatches the traffic there.
http1 traffic can never enter http2 package. If we put grpc into this
picture, there are grpc, http2 and http1 handlers. Then the usage of
NPN/ALPN is not enough to make decision which server conn we should setup
(apparently no idea between http2.ServerConn and grpc.ServerTransport; and
actually I am not convinced using NPN/ALPN is sufficient for http1 and
grpc). To summarize, to design a working solution, we have to find
something which can be used to see the upcoming traffic on the connection
is http1/http2/grpc. NPN/ALPN seems not the choice to me.

Are we able to do the similar thing?
Can


Reply to this email directly or view it on GitHub
#75 (comment).

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

okay, my proposal is sketched as follows:

we can implement a handshaker. The client connects to a http.Server and
then sends a http1.1 GET with some magic string such as "gRpC-sWiTcH". The
corresponding handler will pass that fd to a grpc server (and response to
the client via handshaker too). After that, all the traffic on that fd is
taken care of by the grpc server. Otherwise, the normal http handler will
be used.

On Wed, Apr 22, 2015 at 4:33 PM, Qi Zhao [email protected] wrote:

On Wed, Apr 22, 2015 at 4:04 PM, Xiang Li [email protected]
wrote:

@iamqizhao https://github.com/iamqizhao

It seems @bradfitz https://github.com/bradfitz's http2 server supports
both http1 and http2 at the same time. Here is the related code

https://github.com/bradfitz/http2/blob/91f80303028022bc2034c277126b405a2257d990/server.go#L185-L192

Yep, the idea is to push the divergence stage (http1 or http2) before
there is any real traffic. It uses the usage NPN/ALPN to decide whether
http.Server creates a http2 ServerConn and dispatches the traffic there.
http1 traffic can never enter http2 package. If we put grpc into this
picture, there are grpc, http2 and http1 handlers. Then the usage of
NPN/ALPN is not enough to make decision which server conn we should setup
(apparently no idea between http2.ServerConn and grpc.ServerTransport; and
actually I am not convinced using NPN/ALPN is sufficient for http1 and
grpc). To summarize, to design a working solution, we have to find
something which can be used to see the upcoming traffic on the connection
is http1/http2/grpc. NPN/ALPN seems not the choice to me.

Are we able to do the similar thing?
Can


Reply to this email directly or view it on GitHub
#75 (comment).

from grpc-go.

bakins avatar bakins commented on July 1, 2024

Why not use HTTP Upgrade?

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

On Wed, Apr 22, 2015 at 5:50 PM, Brian Akins [email protected]
wrote:

Why not use HTTP Upgrade?

To me, it means a more complex solution -- http upgrade can help us
differentiate http1 and http2. Then for http2, after http2.Framer.ReadFrame
returns a frame, we can use the content-type header to differentiate grpc
and normal http2. This constructs a 2-layer solution -- on connection
level, we use http upgrade and on per-stream level, we use content-type.
This sounds too complex to me -- keep in mind that we also need to
implement a hook for grpc server to handle normal http2 traffic in this
solution.


Reply to this email directly or view it on GitHub
#75 (comment).

from grpc-go.

bradfitz avatar bradfitz commented on July 1, 2024

This discussion should happen in the normal grpc discussion places first, not in grpc-go. Once a language-neutral plan is agreed upon, then grpc-go can implement it.

In the meantime, users outside of grpc-go can implement a net.Listener/net.Conn that sniffs the beginning traffic and routes depending on whether it looks like a TLS handshake (with the ALPN for "h2") or an plaintext HTTP/1 request "GET / HTTP/1.1" etc.

But let's please not do some gprc-go-specific hack here if other languages don't do the same.

from grpc-go.

xiang90 avatar xiang90 commented on July 1, 2024

@bradfitz Agreed. I will move the discussion to grpc.

from grpc-go.

tv42 avatar tv42 commented on July 1, 2024

@bradfitz That part doesn't help differentiate web traffic from grpc traffic, when they both happen to run over TLS & even the same ALPN. That really is the interesting part.

Actually, I don't see the grpc protocol spec saying anything about what part of it is so special that it can't just look like POST requests to net/http. Anyone have a short answer to that?

from grpc-go.

bradfitz avatar bradfitz commented on July 1, 2024

It's hard to design something until there's a defined problem.

from grpc-go.

acasajus avatar acasajus commented on July 1, 2024

@tv42 Doesn't the mandatory "Content-Type: application/grpc" work for differentiating between grpc and plain http requests? Granted that's once the handshake has passed.

from grpc-go.

tv42 avatar tv42 commented on July 1, 2024

@acasajus Sure, it would, but right now grpc seems to sort of reimplement part of net/http / bradfitz/http2, so it's not clear how one would pass a request to the other. It's not like one could have a http.Handler inspect the headers and call one of two alternate http.Handlers.

from grpc-go.

bradfitz avatar bradfitz commented on July 1, 2024

@tv42, yeah, grpc-go was developed in parallel with bradfitz/http2. They share a framer, but they have different server implementations. So it's not exactly clear whether and where it would be possible to make one defer to the other. I'd personally like to see them unified someday, perhaps with grpc-go just being a handler under http2 itself, using the http2 server code. But then, grpc might be faster doing it by hand. I'm not sure.

from grpc-go.

philips avatar philips commented on July 1, 2024

@xiang90 @bradfitz Where is this discussion happening in the "normal grpc" channels?

from grpc-go.

bradfitz avatar bradfitz commented on July 1, 2024

I actually don't know. I just assumed there was one, since they have a fancy website (http://www.grpc.io/) and all.

from grpc-go.

bradfitz avatar bradfitz commented on July 1, 2024

Looks like https://groups.google.com/forum/#!forum/grpc-io

from grpc-go.

philips avatar philips commented on July 1, 2024

Started the conversation here: https://groups.google.com/d/msg/grpc-io/JnjCYGPMUms/JDmi9-UpDuoJ

from grpc-go.

xiang90 avatar xiang90 commented on July 1, 2024

@iamqizhao @philips

I tend to agree on this https://groups.google.com/forum/#!topic/grpc-io/JnjCYGPMUms. (grpc-java plan)

Can we do something similar in grpc-go?

Thanks.

from grpc-go.

tv42 avatar tv42 commented on July 1, 2024

As the originator of this issue, I'd like to say this: I really don't care about running gRPC over HTTP/1.1. If you want that, please make a separate issue.

What I want is to have a single TCP port that can be accessed both with a modern browser and a gRPC client, where both behave sanely. That can mean always TLS and all gRPC over HTTP/2; whether the browser uses HTTP/2 or HTTP/1.1 is not relevant.

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

On Mon, May 18, 2015 at 10:08 AM, Xiang Li [email protected] wrote:

@iamqizhao https://github.com/iamqizhao @philips
https://github.com/philips

I tend to agree this
https://groups.google.com/forum/#!topic/grpc-io/JnjCYGPMUms. (grpc-java
plan)

Can we do something similar in grpc-go?

As I mentioned before, this will involve some redesign of http2 package. In
general, I suspect whether it is worth doing a lot of redesign and
rewriting to accommodate http1 traffic and I strongly lean to serve http2
and http1 traffic on different ports.

Thanks.


Reply to this email directly or view it on GitHub
#75 (comment).

from grpc-go.

philips avatar philips commented on July 1, 2024

On Mon, May 18, 2015 at 11:02 AM, Qi Zhao [email protected] wrote:

As I mentioned before, this will involve some redesign of http2 package. In
general, I suspect whether it is worth doing a lot of redesign and
rewriting to accommodate http1 traffic and I strongly lean to serve http2
and http1 traffic on different ports.

Would you take patches to make this library do that?

I think the major reason people find gRPC interesting is because it is ran
over http2; and the only reason http2 is interesting is because it is
backwards compatible with http1+tls. "Backwards compatibility" is very
important; I am sure http2 would have been much more elegantly designed if
they decided to run it over a different port. As an example we want to have
a gRPC option for etcd but we need to have it run on the same port so when
people upgrade to etcd v3.0.0 with gRPC they don't need to reconfigure load
balancers, firewalls, or certificates.

from grpc-go.

stapelberg avatar stapelberg commented on July 1, 2024

+1 to what @philips said. I’m exactly in the same boat with http://robustirc.net/, where I’d be happy to switch to gRPC, but not if it involves a separate port.

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

I think with PR#196 and my previous proposal in this thread it is already
possible to serve both http1.1 and grpc traffic on a single port. You need
to write your own credentials.TransportAuthenticator to do some handshake
between client and server. And in ServerHandshake, you can pass rawConn to
your own http1.1 server so that all the traffic on rawConn will be
delivered to http1.1 server.

On Mon, May 18, 2015 at 12:44 PM, Michael Stapelberg <
[email protected]> wrote:

+1 to what @philips https://github.com/philips said. I’m exactly in the
same boat with http://robustirc.net/, where I’d be happy to switch to
gRPC, but not if it involves a separate port.


Reply to this email directly or view it on GitHub
#75 (comment).

from grpc-go.

xiang90 avatar xiang90 commented on July 1, 2024

@iamqizhao

I have tried the way you suggested, which implements a HTTP 1.1 based hand shaking. https://github.com/xiang90/grpchttp/blob/master/server/server.go#L46-L62

But this also requires EVERY client want to talk to the gRPC sever implementing the handshake mechanism. It basically means my gRPC server becomes a special one. (I might make a mistake or misunderstand your suggestion.)

One of the important point of using gRPC is for its generalization. Users can get easily get working gRPC clients in different language very easily.

I looked at the code, and agreed that if we want to get better support we might need to redesign the gRPC server (http2 server?) a little bit. But I think it worth the effort since it will largely improve the adoption of gRPC for existing applications.

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

On Thu, May 28, 2015 at 3:54 PM, Xiang Li [email protected] wrote:

@iamqizhao https://github.com/iamqizhao

I have tried the way you suggested, which implements a HTTP 1.1 based hand
shaking.
https://github.com/xiang90/grpchttp/blob/master/server/server.go#L46-L62

But this also requires EVERY client want to talk to the gRPC sever
implementing the handshake mechanism. It basically means my gRPC server
becomes a special one.

I do not understand why you care other servers.

One of the important point of using gRPC is for its generalization. Users
can get easily get working gRPC clients in different language very easily.

I looked at the code, and agreed that if we want to get better support we
might need to redesign the gRPC server (http2 server?) a little bit. But I
think it worth the effort since it will largely improve the adoption of
gRPC for existing applications.

I personally do not like this approach because it adds some overhead (path
dispatch) to every single rpc regardless whether you use http1 or not.


Reply to this email directly or view it on GitHub
#75 (comment).

from grpc-go.

xiang90 avatar xiang90 commented on July 1, 2024

I do not understand why you care other servers.

I care about other clients. Every client that wants to talk to my server needs to implement the handshaking, since my server is a special one. I do not want make my server a special gRPC server.

from grpc-go.

xiang90 avatar xiang90 commented on July 1, 2024

I personally do not like this approach because it adds some overhead (path
dispatch) to every single rpc regardless whether you use http1 or not.

Path dispatching only happens for dialing, correct? If we can make this low cost, do you want to have a try?

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

On Thu, May 28, 2015 at 4:35 PM, Xiang Li [email protected] wrote:

I do not understand why you care other servers.

I care about other clients. Every client that wants to talk to my server
needs to implement the handshaking, since my server is a special one. I do
not want make my server a special gRPC server.

I assume your clients use your client library and your client library
should implement the handshaker. So this is transparent to your clients.
No?


Reply to this email directly or view it on GitHub
#75 (comment).

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

On Thu, May 28, 2015 at 4:36 PM, Xiang Li [email protected] wrote:

I personally do not like this approach because it adds some overhead (path
dispatch) to every single rpc regardless whether you use http1 or not.

Path dispatching only happens for dialing, correctly? If we can make this
low cost, do you want to have a try?

I think I get lost. What is your proposal to change http2 package? How can
you make it happen only for dialing?


Reply to this email directly or view it on GitHub
#75 (comment).

from grpc-go.

xiang90 avatar xiang90 commented on July 1, 2024

I assume your clients use your client library and your client library
should implement the handshaker. So this is transparent to your clients.
No?

Not necessarily. For example, in etcd we will maintain the go client (go grpc client and the upper level client on top of it).

The community will maintain the clients in other languages. They need to implement the handshaker for etcd special gRPC server. And I am not sure it is easy to do in all available gRPC client bindings. It would be a overhead.

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

On Thu, May 28, 2015 at 4:51 PM, Xiang Li [email protected] wrote:

I assume your clients use your client library and your client library
should implement the handshaker. So this is transparent to your clients.
No?

Not necessarily. For example, in etcd we will maintain the go client (go
grpc client and the upper level client on top of it).

The community will maintain the clients in other languages. They need to
implement the handshaker for etcd special gRPC server. And I am not sure it
is easy to do in all available gRPC client bindings. It would be a overhead.

Got it. But again, it is not an grpc-go specific question and this is not
the right place to discuss and have solution. The topic should go to
grpc-io. In Go world, the handshaker is a mechanism to achieve that (if
both your client and server are written in gRPC-Go) if you need it now.


Reply to this email directly or view it on GitHub
#75 (comment).

from grpc-go.

xiang90 avatar xiang90 commented on July 1, 2024

I think I get lost. What is your proposal to change http2 package? How can
you make it happen only for dialing?

I briefly looked through the spec (I may misunderstand the spec). The path is / Service-Name / {method name}. We can assume gRPC-go owns all the registered server-name path. When dialing, we can pass a service name path and we will be able to distinguish it from other general http request. HTTP handler can then pass the conn to gRPC-go. This means the gRPC-go sever will not control the whole life-cycle of a connection.

from grpc-go.

xiang90 avatar xiang90 commented on July 1, 2024

Got it. But again, it is not an grpc-go specific question and this is not
the right place to discuss and have solution. The topic should go to
grpc-io. In Go world, the handshaker is a mechanism to achieve that (if
both your client and server are written in gRPC-Go) if you need it now.

I totally agree with you. That is why I do not think your suggestion is a very generic solution.

I did ask the same question in grpc-io group. Java is using path dispatching. And they suggest me to explore the same thing in grpc-go. I think it might be doable and reasonable.(Again I am not super familiar with gRPC or gRPC-go, if you think it is reasonable I would love to explore more)

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

On Thu, May 28, 2015 at 4:59 PM, Xiang Li [email protected] wrote:

I think I get lost. What is your proposal to change http2 package? How can
you make it happen only for dialing?

I briefly looked through the spec (I may misunderstand the spec). The path
is / Service-Name / {method name}. We can assume gRPC-go owns all the
registered server-name path. When dialing, we can pass a service name
path and we will be able to distinguish it from other general http request.
HTTP handler can then pass the conn to gRPC-go. This means the gRPC-go
sever will not control the whole life-cycle of a connection.

Connection and service are two completely orthogonal concepts. A connection
can deliver N different services and a service can be delivered on N
different connections. When clients dial, there is 0 knowledge about what
services will run on this connection.


Reply to this email directly or view it on GitHub
#75 (comment).

from grpc-go.

xiang90 avatar xiang90 commented on July 1, 2024

Connection and service are two completely orthogonal concepts.

I understand that.

When clients dial, there is 0 knowledge about what
services will run on this connection.

Why do we care? We just want to distinguish it from non-grpc connections. We can simply pass an arbitrary registered service name path when creating the initial gRPC-go http2 connection.

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

On Thu, May 28, 2015 at 5:02 PM, Xiang Li [email protected] wrote:

Got it. But again, it is not an grpc-go specific question and this is not
the right place to discuss and have solution. The topic should go to
grpc-io. In Go world, the handshaker is a mechanism to achieve that (if
both your client and server are written in gRPC-Go) if you need it now.

I totally agree with you. That is why I do not think your suggestion is a
very generic solution.

Actually it is a quite generic solution. And we use it internally for some
other kind of switching.

I did ask the same question in grpc-io group. Java is using path
dispatching. And they suggest me to explore the same thing in grpc-go. I
think it might be doable and reasonable.(Again I am not super familiar with
gRPC or gRPC-go, if you think it is reasonable I would love to explore more)

I am not aware any grpc server can serve http1 traffic for now. There would
be some miscommunication somewhere. At very least, your understanding about
path dispatching seems not correct according to your previous reply.


Reply to this email directly or view it on GitHub
#75 (comment).

from grpc-go.

xiang90 avatar xiang90 commented on July 1, 2024

At very least, your understanding about
path dispatching seems not correct according to your previous reply.

Which part? Can you give me some explanation?

I think there are two ways:

  1. use the http server do path dispatching for every gRPC call
  2. use the http server do path dispatching for the first one and use this https://github.com/grpc/grpc-go/blob/master/transport/transport.go#L172 to dispatch further calls inside grpc-go as it is today.

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

On Thu, May 28, 2015 at 5:06 PM, Xiang Li [email protected] wrote:

Connection and service are two completely orthogonal concepts.

I understand that.

When clients dial, there is 0 knowledge about what
services will run on this connection.

Why do we care? We just want to distinguish it from non-grpc connections.
We can simply pass an arbitrary registered service name path when creating
the initial gRPC-go http2 connection.

I got your points. But it is actually a kinda handshaking mechanism which
is pretty similar to my former proposal (unidirectional handshake where
server does not send response). Your client needs to send this name to the
server and you run into the same issue. All of your client impl need to
know what is to send first after a conn is setup. Also if your server is
expecting this name, it is a "special" one according to your previous def.

Reply to this email directly or view it on GitHub
#75 (comment).

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

On Thu, May 28, 2015 at 5:13 PM, Xiang Li [email protected] wrote:

At very least, your understanding about
path dispatching seems not correct according to your previous reply.

Which part? Can you give me some explanation?

I think there are two ways:

  1. use the http server do path dispatching for every gRPC call

again, it adds per-rpc overhead.

  1. use the http server do path dispatching for the first one and use
    this
    https://github.com/grpc/grpc-go/blob/master/transport/transport.go#L172
    to dispatch further calls inside grpc-go as it is today.

again, does this require special treatment for each impl of your client --
"special".

In other words, if all grpc versions implements handshaker, do u still
think your server is "special"?


Reply to this email directly or view it on GitHub
#75 (comment).

from grpc-go.

xiang90 avatar xiang90 commented on July 1, 2024

Your client needs to send this name to the
server and you run into the same issue. All of your client impl need to
know what is to send first after a conn is setup. Also if your server is
expecting this name, it is a "special" one according to your previous def.

There is a difference. If the connection is set up without the path, we can delay transferring the ownership of the connection until the first stream is created. And I think we can safely assume if the first stream has gRPC prefix, all following streams within the connection will have.

from grpc-go.

xiang90 avatar xiang90 commented on July 1, 2024

In other words, if all grpc versions implements handshaker, do u still
think your server is "special"?

If all grpc versions implements the handshaker and there is a common documentation talking about the suggested approach for running http1.1/http2.0/gRPC on the same port, I think I am happy to say it is generic approach. And I believe the developers will not consider my server special and a crazy hack.

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

On Thu, May 28, 2015 at 5:22 PM, Xiang Li [email protected] wrote:

Your client needs to send this name to the
server and you run into the same issue. All of your client impl need to
know what is to send first after a conn is setup. Also if your server is
expecting this name, it is a "special" one according to your previous def.

There is a difference. If the connection is set up without the path, we
can delay transferring the ownership of the connection until the first
stream is created. And I think we can safely assume if the first stream has
gRPC prefix, all following streams within the connection will have.

It is a horrible idea to mess up the boundary of connection setup and rpc
performing -- it will add non-trivial and unneccessary complexity to http2
server. It should be a unidirectional handshaking before any rpcs/http
requests issued on this connection -- so now you can see the similarity to
my proposal.


Reply to this email directly or view it on GitHub
#75 (comment).

from grpc-go.

philips avatar philips commented on July 1, 2024

Don't we want to end up essentially having this library be a path dispatcher on top of the generic HTTP2 library? As explained here: https://groups.google.com/d/msg/grpc-io/JnjCYGPMUms/L2c9m5KiR3gJ

I guess what I am saying is that grpc-go should not implement a Server type at all and should essentially be a http.Handler type. Right?

from grpc-go.

bradfitz avatar bradfitz commented on July 1, 2024

@philips, probably. But grpc-go and Go's http2 server support developed independently with different goals (both using the same http2 Framer package). Whether they should be merged is an open question, but one I haven't had time to consider.

from grpc-go.

philips avatar philips commented on July 1, 2024

@bradfitz OK, that makes sense. We anxiously await some direction on this so we can use grpc-go in our projects. In the meantime we will continue our development on different ports in etcd.

from grpc-go.

mwitkow avatar mwitkow commented on July 1, 2024

This would be great for us.
We'd like to host our /statusz (debug pages) end /metrics (Prometheus metrics endpoint) on the same port to
a) make our DNS SRV based service discovery easier (not needing to write two ports)
b) leverage Prometheus scraping to detect whether the actual service endpoint is up

@bradfitz any further thoughts of merging grpc-go with your http2 library to facilitate shared dispatch?

from grpc-go.

soheilhy avatar soheilhy commented on July 1, 2024

I just came across this issue. I think I have solution for this: cmux sniffs the connection payload and multiplexes HTTP and gRPC connections transparently from the same listener similar to what @bradfitz mentioned earlier in the thread.

I modified server.go as an example:
https://gist.github.com/soheilhy/bb272c000f1987f17063

To test this version of server.go, please run:

% go run client/client.go
2015/07/31 10:49:36 Getting feature for point (409146138, -746188906)
...
% go run client/client.go -tls
2015/07/31 10:49:39 Getting feature for point (409146138, -746188906)
....
% curl localhost:10000                                                                                                           
hello http
% curl -k https://localhost:10000
hello http

Right now, it can't serve HTTP2 content (i.e., won't work if you try https://127.0.0.1/ using Chrome) because https://github.com/bradfitz/http2 does not have h2 support. I'm waiting for @bradfitz to consider bradfitz/http2#69. If that gets a greenlight, cmux can serve pretty much anything along side gRPC.

Thanks for your time!

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

Thanks for the contribution. I have not looked into it but it seems you sniffs each and every header frame. This could have potential performance impact (especially for high qps scenarios). Please evaluate it.

from grpc-go.

soheilhy avatar soheilhy commented on July 1, 2024

No, it sniffs the first header frame only, and after that it multiplexes the connection. The assumption is that one connection is either gRPC or otherwise HTTP. It my benchmarks there is no meaningful overhead for long-lived connections. If you have a specific benchmark scenario, I am happy to evaluate it.

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

got it. gRPC sends/receives http2 settings frame before any headers frame. Does this introduce problems? It seems the server should know whether it is gRPC or http before the 1st headers frame.

from grpc-go.

soheilhy avatar soheilhy commented on July 1, 2024

That's right, but AFAICT cmux correctly handles this (as all gRPC examples I could find work with cmux). The SETTINGS frame is always followed by a HEADERS frame and as soon as cmux sees the header frame, the connection is all gRPC's. Please note that cmux is just sniffing the connection, so that when gRPC server starts reading from the connection it will read from the beginning of the stream: sees the SETTINGS frame and will send its ACK, etc.

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

okay, so cmux buffers the frames until it sees HEADERS. Actually, this is pretty much what @xiang90 proposed to me during a visit. The design basically looks good to me.

from grpc-go.

soheilhy avatar soheilhy commented on July 1, 2024

Exactly, it buffers the frames until it sees the first HEADERS frames with a matching field or sees a HEADERS frame with an END_HEADERS flag. Thank you!

from grpc-go.

philips avatar philips commented on July 1, 2024

Where are we on this? Is the consensus that we put up a PR that documents using cmux?

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

I have not gone through cmux impl to see if it resolves all the problems. I
actually plan to have a built-in solution inside gRPC library instead of
relying in cmux. But I have not got time to iron all the wrinkles. I plan
to take some time to fix this after I finish naming and load balance work.

On Wed, Sep 16, 2015 at 5:53 PM, Brandon Philips [email protected]
wrote:

Where are we on this? Is the consensus that we put up a PR that documents
using cmux?


Reply to this email directly or view it on GitHub
#75 (comment).

from grpc-go.

philips avatar philips commented on July 1, 2024

@iamqizhao Do you have any updates on your approach to gRPC and HTTP 1.1 on the same port?

from grpc-go.

iamqizhao avatar iamqizhao commented on July 1, 2024

We will escalate the priority of this issue. I am going to talk to the dev of other languages to have a common solution (probably after thanksgiving) which may be the one proposed in this issue.

from grpc-go.

bradfitz avatar bradfitz commented on July 1, 2024

My plan is to add a ServeHTTP method to *grpc.Server.

It will still be usable as it is today, but you will gain the ability to use it with the net/http package and put it in an HTTP mux, etc.

from grpc-go.

bradfitz avatar bradfitz commented on July 1, 2024

Okay, that wasn't too bad. Few hours of work and bradfitz@72479a4 seems to work. *grpc.Server now has a ServeHTTP method. It needs tests and WriteHeader implemented (for streaming RPCs probably?) and then I'll send a PR.

from grpc-go.

bufdev avatar bufdev commented on July 1, 2024

:)

from grpc-go.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.