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
how to expose hello hello2 hello3 services on one HelloServer #224
Comments
Hey, thanks for this question! So I don't have an official answer to this, but it's an area of interest, and I have a proof of concept for how one might go about it: check out service registry. It basically assumes you have some way of identifying which service your request is for. |
Thank you for responding. I am finding service registry difficult to quickly follow and make use of it. Note you will see the structure/object is called Arith Cheers. |
Thanks for the feedback! As I mentioned above, this is still an area of exploration. If you're looking for a ready to use RPC server that can run on one port and expose multiple services, tarpc doesn't have a solution today. The best it can do is run one service per port. That being said, I linked you above to my current thoughts on how such a thing could work. In case you missed it (I realize the service registry code is convoluted), the user experience would look like this: let registry = BincodeRegistry::default()
.register(
"WriteService".to_string(),
write_service::serve(server.clone()),
)
.register(
"ReadService".to_string(),
read_service::serve(server.clone()),
);
let listener = bincode_transport::listen(&"0.0.0.0:0".parse().unwrap())?;
let server = tarpc::Server::default()
.incoming(listener)
.respond_with(registry.serve()); |
I believe all the effort invested in tarpc will be worth it in the long run. I'm growing to like it, but both rust and tarpc still have some kinks. I copied your service_registry.rs to rs-mfw-tarpc-serviceregistry.rs in the examples directory and However when using your service registry with a service with a more complex type,
This compiler error is really hard for me to overcome unfortunately. Serializing/Deserializing u8 vectors forced me to look more closely into serde crate which tarpc uses indirectly through the bincode crate. I'm starting to realize working with u8 vectors is treated differently/carefully within the rust compiler itself and serde mentions that in its documentation.
I'm still wrapping my head around tweaking the code to use this and hope the above compile error will disappear. Here is the code:
|
Thank you for this example! I'll dig into it soon. |
I failed to make it work with another approach to hold a vector of vector of u8.
I just discovered bytevec: I'm going to try to embed bytevec encoded bytes within a serde structure for the same effect within WriteChunks. I also found the rust array type has chunk functionality but not necessarily what I need for encoding/decoding into something useful for serde unfortunately. It would be nice to find it there instead for nested vectors within structures to be serializeable/deserializeb from within std types.
|
This compiles, but it's noisy code with lots of commented code for discussing what didn't work but should IMHO. I'm looking forward to hearing from you as to what you think should be the adequate layout to get this done as a working complex example that can build and be easily understood by everyone.
|
@omac777 thank you for the examples! Do you happen to have a git repo you're working in? It might be illuminating if I could look at diffs between what worked and what didn't. |
I'm sorry I don't have the above code in a repo, but the last comment that I posted above has the compiled stuff. tarpc seems to work with ok with serde on simple structures, but with Vec<Vec> as a member, it is insufficient IMHO. bytevec helps to trick the compiler everything is ok for serializing/deserializing. It's not beautiful nor straightforward but it's the best I can do working around all the compiler errors about traits/serialize/deserialize. It's definitely a painpoint and wastes a lot of time. There needs to be a more straightforward, higher-level way with zero-cost. Your way was the closest and I can acknowledge that. Having to build idl/proto files in separate files is not as straightforward as the tarpc way for sure. tarpc is the closest golang-rpcx-like experience I could find for rust. I have to admit I really enjoy rpcx, but if I'm going to be a purist rust programmer, I need to find similar capabilities within rust before I can migrate all golang tools into rust. |
I want to comment on something about the above example's output
because of course files aren't always multiples of buffer sizes. So my question is this: Why is it that golang/rpcx is supple enough to handle this correctly and the rust tarpc version to define a similar capability is like pulling teeth? Please consider this as a constructive criticism since I really would like rust to exceed in terms of performance and ease of use. Currently rust/tarpc can only compete in terms of performance, but ease of use is still IMHO. Thank you for listening.
|
I just looked a bit more closely at the first error you posted above.
I want to point out that this doesn't appear to be valid rust syntax. It looks like you're mixing types ( It looks like you're using this in type position, so I suggest you try replacing this with |
Thanks for the reply. I have no intention on asking serde for support. If they don't have it already, it's because they don't plan to support it. I did find a way to circumvent the issue as I stated above with bytevec. I took out all the dead code and comments and here is something that compiles and runs. It's not the polished final version, but the core concepts are correct.
|
I'm glad you got it to work! Can I ask your opinion on the "registry" style service? Is it better than nothing? If you think it's usable, I could publish it to crates.io. |
I think your registry service example is adequate for exposing many services from one server. tarpc is lacking examples. It needs more examples clearly solving common use case problems. You're right about serde. It should be supporting Vec in both bounded and unbounded forms. The bottom line is tarpc should compile in most scenarios users envision using it without seeing the rust compiler error out about insufficient serde support. Having a weakly supported serde makes tarpc weakly supported also. This will affect the rate of adoption of tarpc will be directly related to the strength and versatility of the serde library. Recently I saw a json to golang tool that converts a json file into a golang structure. |
Try this. It's slow and I made a lot of unnecessary clones but I don't care. It works as a prototype for sending small and large files via your tarpc. If you run it again, it will just send the file again with a same filename suffixed with a different timestamp ensuring uniqueness.
|
@tikue is it possible to revive the service registry concept again? Like the server and register multiple services to serve, then on the client side we can use generics to resolve the wanted services. |
I have succeeded in compiling 3 different service implementations within one HelloServer via 3 different modules within one library exposing the 3 different implementation, but there is only one serve() function called and not the other two.
How do I specify HelloServer should be ready to serve up the 3 services on the same port number rather than just one?
Thank you for listening.
The text was updated successfully, but these errors were encountered: