Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gRPC reflections #227

Merged
merged 6 commits into from
Apr 18, 2023
Merged

Conversation

slinkydeveloper
Copy link
Contributor

This PR implements the grpc reflection service in the ingress #192

Comment on lines +107 to +115
pub struct ReflectionRegistry {
reflection_service_state: Arc<ArcSwap<ReflectionServiceState>>,
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tillrohrmann I need your opinion on this design idea: rather than having this new registry, what if we rename MethodDescriptorsRegistry into something like SchemaRegistry to have something more generic, and have a single point where we take care of all the schema shenanigans?

There is a problem with such data structure though, which is that I want its access patterns "optimized" per use case, so I fear it might leak some details of how the reflection service... But perhaps this is fine?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably start with the SchemaRegistry once we see that there is common functionality and common data that can be shared between the different registries. Until then, I would probably continue with the targeted approach. No need to foresee all eventualities right now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

common data that can be shared between the different registries

Common data is definitely already there, given they share the same descriptor pools (which under the hood are Arcs). The problem with keeping them separate is that they might have inconsistent behaviour, given as it is, ReflectionServiceState overwrites symbols with same name, while MethodDescriptorsRegistry won't.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the time being i wired it up in a way that makes more or less sense, although prone to eventual inconsistencies #227 (comment)

Copy link
Contributor

@tillrohrmann tillrohrmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for creating this PR @slinkydeveloper. Support for gRPC reflection is a cool feature which will improve Restate's usability :-) From what I can tell, the changes make sense to me. Concerning whether to unify the registries or not I would probably look for commonalities between the registries and once we see them clearly emerge, then merge the different registries.

src/ingress_grpc/src/reflection.rs Outdated Show resolved Hide resolved
src/ingress_grpc/src/reflection.rs Show resolved Hide resolved
src/ingress_grpc/src/reflection.rs Show resolved Hide resolved
src/ingress_grpc/src/reflection.rs Outdated Show resolved Hide resolved
Comment on lines 56 to 69
match self
.service_names
.binary_search_by(|s| service_response.name.cmp(&s.name))
{
Ok(_) => {
// No need to reinsert
todo!("We should remove the old symbols first? Or we don't allow this at all?")
}
Err(insert_index) => {
// This insert retains the order
self.service_names.insert(insert_index, service_response);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does service_names need to be a sorted vector? Could it also be a HashSet or so?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's optimized for writing it out, where the generated interface requires a vec and not a set

src/ingress_grpc/src/reflection.rs Show resolved Hide resolved
src/meta/src/lib.rs Outdated Show resolved Hide resolved
Comment on lines +107 to +115
pub struct ReflectionRegistry {
reflection_service_state: Arc<ArcSwap<ReflectionServiceState>>,
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably start with the SchemaRegistry once we see that there is common functionality and common data that can be shared between the different registries. Until then, I would probably continue with the targeted approach. No need to foresee all eventualities right now.

@slinkydeveloper slinkydeveloper changed the title [WIP] gRPC reflections gRPC reflections Apr 13, 2023
@slinkydeveloper
Copy link
Contributor Author

slinkydeveloper commented Apr 13, 2023

I think I addressed most of the comments. Now everything is wired up and works correctly.

I took a shortcut of adding the ingress_grpc dependency to meta, otherwise I needed some work to either split the reflections code, or to move it all to service_metadata. Moving all the code requires to add prost, tonic and co to service_metadata, which doesn't seem right. Splitting the reflections code also doesn't look ok because I prefer to keep all this code as much self contained as possible for the time being, as I'm not completely sure we implement correctly the grpc reflections contract, and keeping everything in the same place helps me to iterate faster on that. Also the registry side of the reflections will probably change considerably in the context of #43, hence the shortcut.

Example:

# No need to provide a descriptor anymore when starting grpcurl and grpcui
$ grpcui -plaintext localhost:9090
gRPC Web UI available at http://127.0.0.1:38421/

# grpcurl also provides some query methods
$ grpcurl -plaintext localhost:9090 list
counter.Counter
$ grpcurl -plaintext localhost:9090 describe
counter.Counter is a service:
service Counter {
  rpc Add ( .counter.CounterAddRequest ) returns ( .google.protobuf.Empty );
  rpc Get ( .counter.CounterRequest ) returns ( .counter.GetResponse );
  rpc GetAndAdd ( .counter.CounterAddRequest ) returns ( .counter.CounterUpdateResult );
  rpc Reset ( .counter.CounterRequest ) returns ( .google.protobuf.Empty );
}

Copy link
Contributor

@tillrohrmann tillrohrmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I had only a few minor comments. Also tried the change out and it worked with grpcui and grpcurl :-)

src/ingress_grpc/src/reflection.rs Outdated Show resolved Hide resolved
src/ingress_grpc/src/reflection.rs Show resolved Hide resolved
@slinkydeveloper slinkydeveloper added this to the 1A milestone Apr 18, 2023
@slinkydeveloper slinkydeveloper merged commit e7ac96f into restatedev:main Apr 18, 2023
@slinkydeveloper slinkydeveloper deleted the issues/192 branch April 18, 2023 07:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants