Version 6: Let's talk about easier communication system between Dart and Rust #268
Replies: 13 comments 16 replies
-
Thanks for the idea! Yes, Protobuf does have 'service', so I considered using those inside Rinf. However the full support for it wasn't quit obvious on both sides of Dart and Rust. Maybe we can keep this as an idea, for now :) |
Beta Was this translation helpful? Give feedback.
-
Good for me. In the meantime, I checked for dart and it seems that to make it possible there is no choice but to fork the project. It will need a lot of work. |
Beta Was this translation helpful? Give feedback.
-
Hi @LucaCoduriV , maybe we can discuss this project further. I do agree that if we use Protobuf services, instead of something like I'm planning to make a new branch for experiment and development. If this change turns out to be easier and cleaner than the current system, we might be able to merge it in the next version :) |
Beta Was this translation helpful? Give feedback.
-
I am currently using rinf for a project (https://luzid.app) which has a Flutter UI via Rinf but also needs to allow controlling the Solana Validator via an SDK, i.e. scripts. This is all to say that I'd also love to see something like this integrated into Rinf as then the API implemtantation for the Rinf message handling and that GRPC server would be almost the same. Also the CRUD idea may make sense in some scenarios, but for an app where I basically want to do RPC style function calls the REST pattern gets almost in the way (I just picked whichever Read/Create/Update and repurposed it for what I actually needed). Also to facilitate reuse of the generated proto types (in my case for the GRPC server/client) it'd be useful to override where rinf writes those Rust definitions, so they can be exposed via a core crate (instead of the server having to depend on the hub crate to get to them). Basically I'm gonna provide a PR for that tomorrow so we can get there step by step assuming this is something you want to add. Finally I wanted to say great lib! I attempted something similar a while back rid, but went too far trying to provide all boilerplate and a simple API. However that got super complex quickly and I find the solution to use protobuf instead a very elegant one! |
Beta Was this translation helpful? Give feedback.
-
Great! If we do this experiment, these think would be important:
I've been taking a look at
I'll be happy to accept any kind of ideas or PR, and possibly merge it into the next version if it looks okay. Thank you very much for your participation! I'm looking forward to seeing your solution. P.S. Thank you for choosing Rinf! If you enjoy it, please consider letting others know if they're looking something like this :) |
Beta Was this translation helpful? Give feedback.
-
Just wanted to post the solution I currently came up with. https://gist.github.com/thlorenz/6b16d0a9f2202df6c149cc2095c695ab It includes the It's a three step process:
To be clear the service is used only when running this as a separate GRPC server. The hub and rinf requests still work as before, only that they now use the rust types that are inside that grpc crate. |
Beta Was this translation helpful? Give feedback.
-
Maybe we can declare messages just like before, but only let go of the CRUD concept, and implement a very simple code generation mechanism. So that this Rust function #[rinf::interact]
async fn test(message: MyMessage) -> MyReturn { } becomes this Dart function Future<MyReturn> test(MyMessage message) async { } where Your example looks interesting and respects to the amount of thoughs went into it. However if we want to make it 'efficient' enough, we should not use HTTP for communication for this. We can organize ideas and brainstorm more here :) |
Beta Was this translation helpful? Give feedback.
-
If we decide to provide a simple codegen mechanism like that, a parser library might be needed to analyze Rust code. Tree-sitter
PetitParserI have come up with some ways to make this work, being focused on simplicity, efficiency, and maintainability. If the above idea looks okay, it might be possible to make this happen in not-so-distant future. Anyone who has opinions, please leave your thoughts here! |
Beta Was this translation helpful? Give feedback.
-
Currently, a big work is being undergone to make the communication system way easier. There's a new simple codegen mechanism, and the basic idea is as follows. From Dart to Rust// proto
// [RINF:DART-SIGNAL]
message DataInput { ... } would allow us to do // Dart
dataInputSend(DataInput( ... ), null); and // Rust
let receiver = data_input_receiver();
while let Some(data_input) = receiver.recv().await {
// Custom Rust logic here
} From Rust to Dart// proto
// [RINF:RUST-SIGNAL]
message DataOutput { ... } would allow us to do // Dart
dataOutputStream.listen((dataOutput) {
// Custom Dart logic here
} and // Rust
data_output_send(DataOutput{ ... }, None); This is a breaking change, but I believe it's worth it because it's so much easier to define new endpoints. Sending and listening to messages is much easier and more intuitive than before. It's being developed on I'm just polishing things and improving code to ensure safety, so it will be in the beta phase for a while. We can make breaking API changes during that time. Any opinions are welcome :) |
Beta Was this translation helpful? Give feedback.
-
Rinf 6 beta is out, and the API is fixed. There should be just a bit more polishing and gathering bugs from people(if any). Rinf 6 should be much easier to use. Documentations are also updated. If anyone finds out some unexpected bugs, please let us know! |
Beta Was this translation helpful? Give feedback.
-
Yes I did give this a try, but it didn't solve the problem I had. ^^ Today, I can redo my attempts using the 6.0.0-beta and report what happens in a github issue, so that the problem gets easier to track :) |
Beta Was this translation helpful? Give feedback.
-
I'm still on v4 and just looked at v6 today. For my application I'm having difficulty seeing how use the new design without immense amounts of boilerplate and major redesign. The way I've been using rinf is mostly via RPC style calls. On the dart side I've wrapped all the rinf functions in simple async style calls. So, for example, if I want to read an object from a database on the rust side, I usually just make a read call with an id. class ThingOp {
static Future<Thing> read(int id) async {
const rustRequest = RustRequest(...);
...
final responseMessage = thing_pb.ReadResponse.fromBuffer(
response.message!
);
return responseMessage.effect;
}
} This is easy to use in a button callback or the like, where the callback just sets state in the right place. With the new design, however, now I need to put a whole bunch of StreamBuilders into my build tree, which doesn't fit nicely at all with flutter state management. Worse, if I wanted to have two widgets both reading/updated 'thing's on the same screen, the new signal design would require every streamBuilder to have a filter so that it only gets the things with the id it is managing. This is a lot of extra code and complexity compared to before. I think there is a lot of value in having standard RPC style design patterns out of the box, rather than having users try to recreate them with complex streaming like in v6. Or perhaps I'm missing something and there is an easy way to achieve RPC besides the example in the document? One that doesn't require a streambuilder embedding in the build tree and can work with a simple async call? |
Beta Was this translation helpful? Give feedback.
-
Hi @akhudek, thanks for sharing your opinion. It looks like the new system doesn't work very well for you. This decision was made to remove the big Also, storing states on the Rust side with
It is true that you need to filter signals by some kind of |
Beta Was this translation helpful? Give feedback.
-
Hello, I'd like to share an idea to enhance this project. Protobuf provides services that enable the creation of functions primarily used with gRPC. I think it would be cool to be able to use it to call functions between Rust and Dart. I quickly looked into it, and it seems that Prost for Rust supports this, but I haven't checked the Dart side yet. If you think it's a good idea, I could delve into it further and possibly assist in implementing it.
Beta Was this translation helpful? Give feedback.
All reactions