Coder Social home page Coder Social logo

rpc interceptor about grpc-go HOT 24 CLOSED

grpc avatar grpc commented on July 19, 2024
rpc interceptor

from grpc-go.

Comments (24)

iamqizhao avatar iamqizhao commented on July 19, 2024

We do have related plan. But can you elaborate "audit" and "global rate limiting or synchronization" first so that I can make sure we are on the same page?

from grpc-go.

xiang90 avatar xiang90 commented on July 19, 2024

@iamqizhao

audit: before each actual client rpc invocation, the control will hand over to application pre-defined interceptor first. The interceptor can record the related metrics of the invocation.

synchronization: before each actual server rpc handling, the control will hand over to application pre-defined interceptor first. The interceptor can decide when to actually call the handler to process the request.

All of them can be done by manually adding hooks into the generated stub statically. But there is no good way to do it dynamically.

maybe something like:

client.Intercept(method string, interceptF func(args ...interface{}))

from grpc-go.

iamqizhao avatar iamqizhao commented on July 19, 2024

Why not do them in the application layer?

On Mon, Mar 23, 2015 at 12:09 PM, Xiang Li [email protected] wrote:

@iamqizhao https://github.com/iamqizhao

audit: before each actual client rpc invocation, the control will hand
over to application pre-defined interceptor first. The interceptor can
record the related metrics of the invocation.

Why don't you call it before you make the rpc call? Note that I do not mean
inside the generated code.

synchronization: before each actual server rpc handling, the control will
hand over to application pre-defined interceptor first. The interceptor can
decide when to actually call the handler to process the request.

Ditto, Why don't you call it in the server handler impl?

All of them can be done by manually adding hooks into the generated stub
statically. But there is no good way to do it dynamically.

maybe something like:

client.Intercept(method string, interceptF func(args ...interface{}))


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

from grpc-go.

xiang90 avatar xiang90 commented on July 19, 2024

Why don't you call it before you make the rpc call?

If I have 10 places to do one rpc call, I need to write the code 10 times. To solve that, I need to wrapper round the actual client, which leads to my first point in the issue:

At the client side, we can actually wrapper the client interface with a thin layer. But we still cannot make this happen dynamically at runtime.

For example, if I have a instruments framework, ideally all the grpc calls can be examined by the framework transparently. The application can be unaware of the auditing and the framework can change the way to do the auditing without modifying the application code.

from grpc-go.

xiang90 avatar xiang90 commented on July 19, 2024

@iamqizhao I just found there is something related in java implementation:
https://github.com/grpc/grpc-java/blob/master/core/src/main/java/io/grpc/ClientInterceptor.java

Personally, I think adding a thin wrapper around the generated interface might be good enough for the common cases. But adding the ability to intercept the rpc invocation and handling might still be useful, at least in the case I described.

from grpc-go.

iamqizhao avatar iamqizhao commented on July 19, 2024

On Mon, Mar 23, 2015 at 1:53 PM, Xiang Li [email protected] wrote:

Why don't you call it before you make the rpc call?

If I have 10 places to do one rpc call, I need to write the code 10 times.
To solve that, I need to wrapper round the actual client, which leads to my
first point in the issue:

not really. You can wrap it into a struct so that you only write the code
once. Again, wrapping is not in the generated code. The same approach
applies to the server side too.

At the client side, we can actually wrapper the client interface with a thin layer. But we still cannot make this happen dynamically at runtime.

For example, if I have a instruments framework, ideally all the grpc calls
can be examined by the framework transparently. The application can be
unaware of the auditing and the framework can change the way to do the
auditing without modifying the application code.

Actually our prior experience indicates that pushing all these complexities
into a generic library is a bad idea. We do not have plan to to support
generic interceptor (except java) in grpc.


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

from grpc-go.

iamqizhao avatar iamqizhao commented on July 19, 2024

On Mon, Mar 23, 2015 at 2:00 PM, Xiang Li [email protected] wrote:

@iamqizhao https://github.com/iamqizhao I just found there is something
related in java implementation:

https://github.com/grpc/grpc-java/blob/master/core/src/main/java/io/grpc/ClientInterceptor.java

Yup, this is java specific thing. we do not have plan to support
interceptor for other languages.

Personally, I think adding a thin wrapper around the generated interface
might be good enough for the common cases. But adding the ability to
intercept the rpc invocation and handling might still be useful, at least
in the case I described.


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

from grpc-go.

xiang90 avatar xiang90 commented on July 19, 2024

not really. You can wrap it into a struct so that you only write the code
once. Again, wrapping is not in the generated code. The same approach
applies to the server side too.

I understand that. But I cannot create the struct dynamically as I mentioned.
Even if golang supports making a struct at runtime, this will add a great amount of
complexity comparing to add a "hook place" in the generated code.

We do not have plan to to support generic interceptor (except java) in grpc.

Can you talk a little bit about your plan? Thanks!

from grpc-go.

iamqizhao avatar iamqizhao commented on July 19, 2024

On Mon, Mar 23, 2015 at 2:13 PM, Xiang Li [email protected] wrote:

not really. You can wrap it into a struct so that you only write the code
once. Again, wrapping is not in the generated code. The same approach
applies to the server side too.

I understand that. But I cannot create the struct dynamically as I
mentioned.
Even if golang supports make a struct at runtime, this will add a great
amount of
complexity comparing to add a "hook place" in the generated code.

I do not get it. what is the problem with

func callFoo(ctx context.Context, client yourpb.XXXClient, arg
proto.Message, f func(...interface{}), hargs ...interface{})
(proto.Message, error) {
if f != nil {
f(hargs...)
}
return client.Foo(ctx, arg)
}

We do not have plan to to support generic interceptor (except java) in
grpc.

Can you talk a little bit about your plan? Thanks!

There won't be generic interceptor support unless there is a huge demand
for that. It can be done in application layer.


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

from grpc-go.

hongchaodeng avatar hongchaodeng commented on July 19, 2024

Hi @iamqizhao .

Thanks for the replying. I've been following this issue.

Let me clarify our problem. We let user to define their grpc service and messages. It's beneficial because it makes serialization and network communication of messages more efficient (via zero copy, if supported by grpc).

While user define grpc service and messages, our framework needs a layer between (user) grpc service methods and actual serialization/networking:

func serviceCalled(methodName string, ctx context.Context, input proto.Message) (ctx context.Context, input proto.Message) {}
func messageReturned(methodName string, ctx context.Context, output proto.Message, err error) (output proto.Message, err error) {}

This would be super awesome if grpc can support it. I believe there are many more use cases.

And the same thing applies to client side to add dynamic wrapper, which we uses grpc.Invoke as a hack now. A official generic layer would be very nice to handle this problem.

from grpc-go.

iamqizhao avatar iamqizhao commented on July 19, 2024

On Mon, Mar 23, 2015 at 4:58 PM, Hongchao Deng [email protected]
wrote:

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

Thanks for the replying. I've been following up in this issue.

Let me clarify our problem. We let user to define their grpc service and
messages. It's beneficial because it makes serialization and network
communication of messages more efficient (via zero copy, if supported by
grpc).

While user define grpc service and messages, our framework needs a layer
between (user) grpc service methods and actual serialization/networking:

func serviceCalled(methodName string, ctx context.Context, input proto.Message) (context.Context, proto.Message)
func messageReturned(methodName string, ctx context.Context, output proto.Message, err error) (proto.Message, error)

This would be super awesome if grpc can support it. I believe there are
many more use cases.

I think there is probably a design flaw here (or I misunderstood
something). There are two typical ways to host a service using grpc/other
rpc framework:
i) expose grpc to users directly. In that case, the service provider only
provide service on server side and zero control on client side;
ii) wrap grpc as an internal communication mechanism and write your own
client library exposing to your users.
Your use case seems not fall into either of them -- you expose grpc to
users directly but require some amount of control on client side in
meanwhile (so that
you want grpc itself to provide this control layer and corresponding hook
for you but I think it is not right thing to do).

Xiaoyun should know this. Or probably we still have some miscommunications
here. I can talk to Xiaoyun in person if you guys think it is helpful.


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

from grpc-go.

xiang90 avatar xiang90 commented on July 19, 2024

@iamqizhao Thanks. Closing.

from grpc-go.

xiaoyunwu avatar xiaoyunwu commented on July 19, 2024

@iamqizhao, sorry I am late to this thread, on airplane.

One of the reason we liked grpc is that it provides typed method directly to application, so that application can be written in an domain natural way without worry about serialization, and dispatching (if one have to use http directly).

Scanning through the threads, I think there is a miscommunication (or at least the wording suggested so). I agree that your callFoo is a good idiom, but only for application. Not for framework. The project that we worked (taskgraph) is actually at framework, by that I mean we expect many different machine learning applications can be build on top of this. In fact, we might have different framework implementations, each provide different semantics (BSP, the current implementation is just an example).

When defined on host:port level, grpc is really a low level interface. Application might want to have the same typed method call at higher level. For example, assume that we have multiple replica of the same service, and we want to do automatic retries between them, or send request to all of them, and return when the first response come back. While it is easy to wrap each rpc service in each application, but that will requires many code duplication, which is bad. Also, some of these things might be hard to get it right, without leaving hooks so that it makes it easy to write framework level code will only make go programmer life harder.

I did not really following your argument here, can you elaborate a bit more.
"Actually our prior experience indicates that pushing all these complexities
into a generic library is a bad idea. We do not have plan to to support
generic interceptor (except java) in grpc."

If I go with my understanding of what it is, I think we are not ask grpc-go to provide a generic library, mere the ability to write such generic library. I do not think possibility of writing a bad generic library is a good reason to do not support the attempt to write one.

GRPC is one of the things that I miss when I left google (among many other things), while I understand that applications might represented most of current grpc users, I think adding support to allow write framework level code will only make it more usable.

So the question we have really is how do we write framework level code in grpc-go?

from grpc-go.

iamqizhao avatar iamqizhao commented on July 19, 2024

On Tue, Mar 24, 2015 at 6:02 AM, xiaoyunwu [email protected] wrote:

@iamqizhao https://github.com/iamqizhao, sorry I am late to this
thread, on airplane.

One of the reason we liked grpc is that it provides typed method directly
to application, so that application can be written in an domain natural way
without worry about serialization, and dispatching (if one have to use http
directly).

Scanning through the threads, I think there is a miscommunication (or at
least the wording suggested so). I agree that your callFoo is a good idiom,
but only for application. Not for framework. The project that we worked
(taskgraph) is actually at framework, by that I mean we expect many
different machine learning applications can be build on top of this. In
fact, we might have different framework implementations, each provide
different semantics (BSP, the current implementation is just an example).

Your framework is still an APPLICATION from the point of view of grpc. I am
not clear what your project does. But per my previous email, I think the
right approach for your project is to provide your client library (probably
and server library) to your users instead of exposing grpc directly. Recall
that how bigtable, GFS, chubby etc. do using google internal rpc library.

When defined on host:port level, grpc is really a low level interface.
Application might want to have the same typed method call at higher level.
For example, assume that we have multiple replica of the same service, and
we want to do automatic retries between them, or send request to all of
them, and return when the first response come back. While it is easy to
wrap each rpc service in each application, but that will requires many code
duplication, which is bad. Also, some of these things might be hard to get
it right, without leaving hooks so that it makes it easy to write framework
level code will only make go programmer life harder.

grpc is NOT defined on host:port level. load balancing channel and name
service is under design right now, which achieves most of what you
described above.

I did not really following your argument here, can you elaborate a bit
more.
"Actually our prior experience indicates that pushing all these
complexities
into a generic library is a bad idea. We do not have plan to to support
generic interceptor (except java) in grpc."

gRPC is a generic library -- it does not bind to a particular application.
I think this also clears your following confusion.

If I go with my understanding of what it is, I think we are not ask
grpc-go to provide a generic library, mere the ability to write such
generic library. I do not think possibility of writing a bad generic
library is a good reason to do not support the attempt to write one.

GRPC is one of the things that I miss when I left google (among many other
things), while I understand that applications might represented most of
current grpc users, I think adding support to allow write framework level
code will only make it more usable.

GRPC is not the thing you miss because it was born after you left Google.
It must be something else. :P

So the question we have really is how do we write framework level code
in grpc-go?

My suggestion would be following how bigtable/gfs architects their
framework.


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

from grpc-go.

hongchaodeng avatar hongchaodeng commented on July 19, 2024

Hi. I think it's a little out of track. Let me give an example.

Let's say user provide a message definition:

message userMsg {
   ...
}

We might want the rpc call to handle serialization:

rpcCall (input *ourPb.Input, userMsg proto.Message)

Otherwise, we have to add a bytes field:

message ourMsg {
...
bytes userData
}

In this way, we can save the computing time and mem space for serialization work. We can only do serialization once and send it over network. Otherwise we have to serialize twice and they are all in user space. This is particularly important when we handling a large size user data.

from grpc-go.

hongchaodeng avatar hongchaodeng commented on July 19, 2024

Just like netty SimpleChannelInboundHandler.

It hands over the serialization work to communication layer. As long as user defines Decode() method (in grpc case, as long as it's proto message), netty/grpc would handle it.

from grpc-go.

iamqizhao avatar iamqizhao commented on July 19, 2024

Doesn't grpc do the serialization work for applications already? Or you
tried to use this as an example to demonstrate why an interceptor is
needed? You seem to move the discussion back to the track. But
unfortunately it makes me completely lost. What is your real question?

On Tue, Mar 24, 2015 at 2:18 PM, Hongchao Deng [email protected]
wrote:

Just like netty SimpleChannelInboundHandler
http://netty.io/4.0/api/io/netty/channel/SimpleChannelInboundHandler.html
.

It hands over the serialization work to communication layer. In this way,
it's more efficient. As long as user defines Decode() method (in grpc case,
as long as it's proto message), netty/grpc would handle it.


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

from grpc-go.

hongchaodeng avatar hongchaodeng commented on July 19, 2024

Doesn't grpc do the serialization work for applications already?

That's right. There are actually two layers of "application". We use grpc to transfer messages over network. Message would look like this:

message Entry {
    required uint64     Type  = 1;
    required uint64     Term  = 2;
    required uint64     Index = 3;
    optional bytes      UserData  = 4;
}

The 4th field is actually carrying the user data. User is likely to define a proto message, and then serialize it in order to put in 4th field. This could be huge cost. Think that we are carrying 2GB user data. Serializing it TWICE would be huge cost. Not to mention that it could be improved more in zero copy in network communication.

Can we put the entire grpc layer to user? No, we still need the other metadata (Type, Term, Index, etc.) and some control. One example would be:

https://github.com/coreos/etcd/blob/9b4d52ee73e9b4d62e506f981db4887326a6b3e0/raft/raftpb/raft.proto#L20
https://github.com/coreos/etcd/blob/d9b5b56c82a3f9a7a5f9bd9f5be5e2372ef33cd6/raft/multinode.go#L387

Ideally, it's about huge data transfer and improving efficiency in serialization and network communication.

from grpc-go.

xiaoyunwu avatar xiaoyunwu commented on July 19, 2024

ok, right when I say grpc, I really meant stubby. I know they are
different, but they are all google rpc implementations. :-)

I understand from your point of view, our framework indeed look like
application. But I want to make a distinction using the following text
based digram: <-text->, text inside <- and -> describe the nature of the
interaction between modules or layers.

the grpc/application split in your mind:
grpc <- typed method call defined by application-> application
which basically mean that application can talk use grpc for typed method
call that are defined by application themself.

I do not think I made it clear in my last email, our framework want to act
as man in the middle and adding certain framework specific checks, so we
have three way splits:

grpc <- -> taskgraph framework <-typed method call defined by application->
application

Here between our framework and application, again we want to allow
application to define/implement typed method call, taskgraph can be just as
low level as grpc from application point of view.

So there is the difference between your view from grpc and our view from
application side.

Among other things, we try to provide a generic block synchronous parallel
framework implementation, we might want to on the server side check whether
the request is in the same epoch or not, and we want to have the option not
to burden application developer with framework logic. To do that, the only
easy and elegant way is to be able to write service forwarding in generic
fashion. If you have other solutions, we are happy to learn.

I can understand that you do not want to expose too much. And load
balancing channel and name service will be definitely useful. Are these
mainly a client side things, or will there be some server side construction
as well. And is it possible to use the similar technique to add framework
logic in a generic fashion.

One last thing, I am just wondering whether you can go a bit into detail
why java have generic interceptor and go does not?

I am sorry it takes lot of your time, and I can imagine that this will be a
smaller request, which have many different hacks. On this front, do you
know effort that people hack the code generation?

Xiaoyun

On Wed, Mar 25, 2015 at 5:08 AM, Qi Zhao [email protected] wrote:

On Tue, Mar 24, 2015 at 6:02 AM, xiaoyunwu [email protected]
wrote:

@iamqizhao https://github.com/iamqizhao, sorry I am late to this
thread, on airplane.

One of the reason we liked grpc is that it provides typed method directly
to application, so that application can be written in an domain natural
way
without worry about serialization, and dispatching (if one have to use
http
directly).

Scanning through the threads, I think there is a miscommunication (or at
least the wording suggested so). I agree that your callFoo is a good
idiom,
but only for application. Not for framework. The project that we worked
(taskgraph) is actually at framework, by that I mean we expect many
different machine learning applications can be build on top of this. In
fact, we might have different framework implementations, each provide
different semantics (BSP, the current implementation is just an example).

Your framework is still an APPLICATION from the point of view of grpc. I am
not clear what your project does. But per my previous email, I think the
right approach for your project is to provide your client library (probably
and server library) to your users instead of exposing grpc directly. Recall
that how bigtable, GFS, chubby etc. do using google internal rpc library.

When defined on host:port level, grpc is really a low level interface.
Application might want to have the same typed method call at higher
level.
For example, assume that we have multiple replica of the same service,
and
we want to do automatic retries between them, or send request to all of
them, and return when the first response come back. While it is easy to
wrap each rpc service in each application, but that will requires many
code
duplication, which is bad. Also, some of these things might be hard to
get
it right, without leaving hooks so that it makes it easy to write
framework
level code will only make go programmer life harder.

grpc is NOT defined on host:port level. load balancing channel and name
service is under design right now, which achieves most of what you
described above.

I did not really following your argument here, can you elaborate a bit
more.
"Actually our prior experience indicates that pushing all these
complexities
into a generic library is a bad idea. We do not have plan to to support
generic interceptor (except java) in grpc."

gRPC is a generic library -- it does not bind to a particular application.
I think this also clears your following confusion.

If I go with my understanding of what it is, I think we are not ask
grpc-go to provide a generic library, mere the ability to write such
generic library. I do not think possibility of writing a bad generic
library is a good reason to do not support the attempt to write one.

GRPC is one of the things that I miss when I left google (among many
other
things), while I understand that applications might represented most of
current grpc users, I think adding support to allow write framework level
code will only make it more usable.

GRPC is not the thing you miss because it was born after you left Google.
It must be something else. :P

So the question we have really is how do we write framework level code
in grpc-go?

My suggestion would be following how bigtable/gfs architects their
framework.


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


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

from grpc-go.

xiaoyunwu avatar xiaoyunwu commented on July 19, 2024

Sorry, one more thing. The bigtable and gfs actually provide a low level
api to application, and all serialization are controlled by application. We
try to piggyback on the good work by grpc so application can design and
implement their logic in an higher level interface, without worry about
serialization.

On Wed, Mar 25, 2015 at 6:00 AM, Xiaoyun Wu [email protected] wrote:

ok, right when I say grpc, I really meant stubby. I know they are
different, but they are all google rpc implementations. :-)

I understand from your point of view, our framework indeed look like
application. But I want to make a distinction using the following text
based digram: <-text->, text inside <- and -> describe the nature of the
interaction between modules or layers.

the grpc/application split in your mind:
grpc <- typed method call defined by application-> application
which basically mean that application can talk use grpc for typed method
call that are defined by application themself.

I do not think I made it clear in my last email, our framework want to act
as man in the middle and adding certain framework specific checks, so we
have three way splits:

grpc <- -> taskgraph framework <-typed method call defined by
application-> application

Here between our framework and application, again we want to allow
application to define/implement typed method call, taskgraph can be just as
low level as grpc from application point of view.

So there is the difference between your view from grpc and our view from
application side.

Among other things, we try to provide a generic block synchronous parallel
framework implementation, we might want to on the server side check whether
the request is in the same epoch or not, and we want to have the option not
to burden application developer with framework logic. To do that, the only
easy and elegant way is to be able to write service forwarding in generic
fashion. If you have other solutions, we are happy to learn.

I can understand that you do not want to expose too much. And load
balancing channel and name service will be definitely useful. Are these
mainly a client side things, or will there be some server side construction
as well. And is it possible to use the similar technique to add framework
logic in a generic fashion.

One last thing, I am just wondering whether you can go a bit into detail
why java have generic interceptor and go does not?

I am sorry it takes lot of your time, and I can imagine that this will be
a smaller request, which have many different hacks. On this front, do you
know effort that people hack the code generation?

Xiaoyun

On Wed, Mar 25, 2015 at 5:08 AM, Qi Zhao [email protected] wrote:

On Tue, Mar 24, 2015 at 6:02 AM, xiaoyunwu [email protected]
wrote:

@iamqizhao https://github.com/iamqizhao, sorry I am late to this
thread, on airplane.

One of the reason we liked grpc is that it provides typed method
directly
to application, so that application can be written in an domain natural
way
without worry about serialization, and dispatching (if one have to use
http
directly).

Scanning through the threads, I think there is a miscommunication (or at
least the wording suggested so). I agree that your callFoo is a good
idiom,
but only for application. Not for framework. The project that we worked
(taskgraph) is actually at framework, by that I mean we expect many
different machine learning applications can be build on top of this. In
fact, we might have different framework implementations, each provide
different semantics (BSP, the current implementation is just an
example).

Your framework is still an APPLICATION from the point of view of grpc. I
am
not clear what your project does. But per my previous email, I think the
right approach for your project is to provide your client library
(probably
and server library) to your users instead of exposing grpc directly.
Recall
that how bigtable, GFS, chubby etc. do using google internal rpc library.

When defined on host:port level, grpc is really a low level interface.
Application might want to have the same typed method call at higher
level.
For example, assume that we have multiple replica of the same service,
and
we want to do automatic retries between them, or send request to all of
them, and return when the first response come back. While it is easy to
wrap each rpc service in each application, but that will requires many
code
duplication, which is bad. Also, some of these things might be hard to
get
it right, without leaving hooks so that it makes it easy to write
framework
level code will only make go programmer life harder.

grpc is NOT defined on host:port level. load balancing channel and name
service is under design right now, which achieves most of what you
described above.

I did not really following your argument here, can you elaborate a bit
more.
"Actually our prior experience indicates that pushing all these
complexities
into a generic library is a bad idea. We do not have plan to to support
generic interceptor (except java) in grpc."

gRPC is a generic library -- it does not bind to a particular application.
I think this also clears your following confusion.

If I go with my understanding of what it is, I think we are not ask
grpc-go to provide a generic library, mere the ability to write such
generic library. I do not think possibility of writing a bad generic
library is a good reason to do not support the attempt to write one.

GRPC is one of the things that I miss when I left google (among many
other
things), while I understand that applications might represented most of
current grpc users, I think adding support to allow write framework
level
code will only make it more usable.

GRPC is not the thing you miss because it was born after you left Google.
It must be something else. :P

So the question we have really is how do we write framework level code
in grpc-go?

My suggestion would be following how bigtable/gfs architects their
framework.


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


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

from grpc-go.

iamqizhao avatar iamqizhao commented on July 19, 2024

On Tue, Mar 24, 2015 at 2:56 PM, Hongchao Deng [email protected]
wrote:

Doesn't grpc do the serialization work for applications already?
That's right. But there are two layers in "application". We use grpc to
transfer messages over network. Message would look like this:

message Entry {
required uint64 Type = 1;
required uint64 Term = 2;
required uint64 Index = 3;
optional bytes UserData = 4;

The fourth field is actually carrying the user data. User has defined a
proto message, and then serialize in order to put it in fourth field. This
could be huge cost. Think that we are carrying 2GB user data. Serializing
it TWICE would be huge cost. Not to mention that it could improved more in
zero copy in network communication.

okay, I see the problem here. This cannot be addressed now because the
open-sourced protobuf does not have this kind of zero-copy support (the
internal version does have). But I am wondering how this can be resolved
with a interceptor?

What if we put the entire grpc layer to user? No, we still need the other
metadata and some control. One example would be:

https://github.com/coreos/etcd/blob/master/raft/raftpb/raft.proto#L20
https://github.com/coreos/etcd/blob/master/raft/multinode.go#L387

Ideally, it's about huge data transfer and improving efficiency in
serialization and network communication.


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

from grpc-go.

xiaoyunwu avatar xiaoyunwu commented on July 19, 2024

If there is server side interception, we can first introduce an new type:

type Message interface {
proto.Message

// These two functions allow framework to piggy back the meta information
// it need to carry out its work.
GetMeta() Meta
SetMeta(m Meta)
}

we then as application define/implement their grpc service as usual, but in
your generic service interceptor, we define interface based Message as
oppose to proto.Message, this way, framework can have a chance on server
side to manipulate meta info needed by taskgraph, but still have grpc takes
care of serialization issues in one shot. This is still a work around, but
at least it meets our goal as allowing application define their own message
passing.

On Wed, Mar 25, 2015 at 8:16 AM, Qi Zhao [email protected] wrote:

On Tue, Mar 24, 2015 at 2:56 PM, Hongchao Deng [email protected]
wrote:

Doesn't grpc do the serialization work for applications already?
That's right. But there are two layers in "application". We use grpc to
transfer messages over network. Message would look like this:

message Entry {
required uint64 Type = 1;
required uint64 Term = 2;
required uint64 Index = 3;
optional bytes UserData = 4;

The fourth field is actually carrying the user data. User has defined a
proto message, and then serialize in order to put it in fourth field.
This
could be huge cost. Think that we are carrying 2GB user data. Serializing
it TWICE would be huge cost. Not to mention that it could improved more
in
zero copy in network communication.

okay, I see the problem here. This cannot be addressed now because the
open-sourced protobuf does not have this kind of zero-copy support (the
internal version does have). But I am wondering how this can be resolved
with a interceptor?

What if we put the entire grpc layer to user? No, we still need the other
metadata and some control. One example would be:

https://github.com/coreos/etcd/blob/master/raft/raftpb/raft.proto#L20
https://github.com/coreos/etcd/blob/master/raft/multinode.go#L387

Ideally, it's about huge data transfer and improving efficiency in
serialization and network communication.


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


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

from grpc-go.

iamqizhao avatar iamqizhao commented on July 19, 2024

On Tue, Mar 24, 2015 at 5:16 PM, Qi Zhao [email protected] wrote:

On Tue, Mar 24, 2015 at 2:56 PM, Hongchao Deng [email protected]
wrote:

Doesn't grpc do the serialization work for applications already?
That's right. But there are two layers in "application". We use grpc to
transfer messages over network. Message would look like this:

message Entry {
required uint64 Type = 1;
required uint64 Term = 2;
required uint64 Index = 3;
optional bytes UserData = 4;

The fourth field is actually carrying the user data. User has defined a
proto message, and then serialize in order to put it in fourth field. This
could be huge cost. Think that we are carrying 2GB user data. Serializing
it TWICE would be huge cost. Not to mention that it could improved more in
zero copy in network communication.

okay, I see the problem here. This cannot be addressed now because the
open-sourced protobuf does not have this kind of zero-copy support (the
internal version does have). But I am wondering how this can be resolved
with a interceptor?

BTW, I do not see this is the problem for grpc only. How can you avoid it
in your previous http based solution? If you pass all these uint64 fields
as http headers, grpc can do the same thing already.

What if we put the entire grpc layer to user? No, we still need the other

metadata and some control. One example would be:

https://github.com/coreos/etcd/blob/master/raft/raftpb/raft.proto#L20
https://github.com/coreos/etcd/blob/master/raft/multinode.go#L387

Ideally, it's about huge data transfer and improving efficiency in
serialization and network communication.


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

from grpc-go.

xiaoyunwu avatar xiaoyunwu commented on July 19, 2024

In the last round, we did not allow application to define typed rpc method.
Instead, they are only allowed to implement a rather low level method:

Serve(taskID uint64, meta string, input []byte) []byte

Where user have to manually handle serialization and method dispatching.

Xiaoyun

On Wed, Mar 25, 2015 at 10:55 AM, Qi Zhao [email protected] wrote:

On Tue, Mar 24, 2015 at 5:16 PM, Qi Zhao [email protected] wrote:

On Tue, Mar 24, 2015 at 2:56 PM, Hongchao Deng <[email protected]

wrote:

Doesn't grpc do the serialization work for applications already?
That's right. But there are two layers in "application". We use grpc to
transfer messages over network. Message would look like this:

message Entry {
required uint64 Type = 1;
required uint64 Term = 2;
required uint64 Index = 3;
optional bytes UserData = 4;

The fourth field is actually carrying the user data. User has defined a
proto message, and then serialize in order to put it in fourth field.
This
could be huge cost. Think that we are carrying 2GB user data.
Serializing
it TWICE would be huge cost. Not to mention that it could improved more
in
zero copy in network communication.

okay, I see the problem here. This cannot be addressed now because the
open-sourced protobuf does not have this kind of zero-copy support (the
internal version does have). But I am wondering how this can be resolved
with a interceptor?

BTW, I do not see this is the problem for grpc only. How can you avoid it
in your previous http based solution? If you pass all these uint64 fields
as http headers, grpc can do the same thing already.

What if we put the entire grpc layer to user? No, we still need the other

metadata and some control. One example would be:

https://github.com/coreos/etcd/blob/master/raft/raftpb/raft.proto#L20
https://github.com/coreos/etcd/blob/master/raft/multinode.go#L387

Ideally, it's about huge data transfer and improving efficiency in
serialization and network communication.


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


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

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.