stepancheg / grpc-rust

Rust implementation of gRPC
MIT License
1.37k stars 124 forks source link

Multiple services on one server/port #75

Closed Boscop closed 7 years ago

Boscop commented 7 years ago

I don't see a way to serve multiple gRPC services (for different 'concerns') on one server/port. Is there a way? In offical libs for Go at least it's generatedpackagename.RegisterServiceNameServer(srv, impl)

Can it be done like this? https://github.com/stepancheg/grpc-rust/blob/master/grpc-examples/src/bin/greeter_server_multi_server.rs#L30-L31

Can you please explain that example, why are there two instances of the same service started, when one is enough to serve multiple clients?

Similarly, if one client executable wants to use multiple services, can it reuse the same connection among the different instantiated clients? (In Go it'd be NewServiceNameClient(clientconn).)

stepancheg commented 7 years ago

If I understood you correctly, you want to have multiple service implementation on single port. E. g.

struct Service1Impl; struct Service2Impl; // your implementations
impl Service1 for Service1Impl {} impl Service2 for Service2Impl {}

In that case you need to do something like that:

let s1 = Service1Server::new_service_def(Service1Impl);
let s2 = Service1Server::new_service_def(Service2Impl);
// create a service from two services
let joined_service = ServerServiceDefinition.join(vec![s1, s2]);

let server = GrpcServer::new_plain(addr, conf, joined_service);

greeter_server_multi_server.rs is an example of how to run multiple event loops on single port, if single-threaded server is a bottleneck.

Similarly, if one client executable wants to use multiple services, can it reuse the same connection among the different instantiated clients?

No, it is not possible. It is easy to implement in rust-protobuf, and the question is what API should look like. I've created as issue: #76.

Boscop commented 7 years ago

Thanks! So in the example that's not the multi server, only one client can be served at a time? There is no way to spawn a new thread for every client, right? (Because it just awaits the underlying futures?)

stepancheg commented 7 years ago

There are two ways to start your server, and there are two ways to implement your service.

Server can be started as:

Your service can be implemented:

If you executed service in event loop thread, and your implementation is synchronous, you can serve only one client at at a time. In all other combinations, requests execute concurrently.

Boscop commented 7 years ago

I see. So in the greeter_server_multi_server example, it can serve 2 requests at a time? If that's the case, why would someone do it like that, instead of using a thread pool?

stepancheg commented 7 years ago

Probably I haven't explained properly. Just to be clear. You can serve two requests at a time with single server with either thread pool or asynchrnous implementation of service.

Why would someone want to use multi-server? I can think of two reasons:

Boscop commented 7 years ago

Ah, makes sense, thanks.

stepancheg commented 7 years ago

Welcome! If you have more questions, please don't hesistate to ask. Documentation is terrible and questions would help me to understand what I should do next.