fzyzcjy / flutter_rust_bridge

Flutter/Dart <-> Rust binding generator, feature-rich, but seamless and simple.
https://fzyzcjy.github.io/flutter_rust_bridge/
MIT License
4.27k stars 300 forks source link

Can't send dart version of rust object in SendPort #2321

Closed msiler closed 1 week ago

msiler commented 1 month ago

Describe the bug

Thanks for creating this great library!

I created a struct in Rust and generated the Dart version of it. I'm trying to send it through a SendPort, but I'm getting an error that seems to indicate that you can't send RustArc in a SendPort. Specifically the error is:

ArgumentError (Invalid argument(s): Illegal argument in isolate message: object is unsendable - Library:'package:flutter_rust_bridge/src/rust_arc/_common.dart' Class: RustArc (see restrictions listed at `SendPort.send()` documentation for more information)

I searched the documentation and github issues, but didn't find any related information. Is there a workaround for this?

Steps to reproduce

  1. Create simple struct in Rust
  2. Use flutter_rust_bridge_codegen generate to generate corresponding Dart code
  3. Create a ReceivePort and give its SendPort to a new Isolate. Try to call sendPort.send() with the Dart version of the Rust struct.

Logs

I don't think this is a generation issue, but I can add logs if needed.

Expected behavior

No response

Generated binding code

No response

OS

Linux

Version of flutter_rust_bridge_codegen

2.3.0

Flutter info

No response

Version of clang++

No response

Additional context

No response

welcome[bot] commented 1 month ago

Hi! Thanks for opening your first issue here! :smile:

fzyzcjy commented 1 month ago

Hmm, I guess it is because it contains some pointer etc. And I wonder whether sending it to another isolate will cause the dispose/GC logic to somehow change (possibly it's OK but not tested).

One way is to PR to allow such usage. Another workaround may be, put your Rust objects at Rust side (say, a HashMap), and only pass around an integer index here and there.

Btw, what is your real scenario that requires sending across isolates? Maybe by discussing that we can find a way to avoid using isolates or avoid using this proposed feature.

msiler commented 1 month ago

Btw, what is your real scenario that requires sending across isolates? Maybe by discussing that we can find a way to avoid using isolates or avoid using this proposed feature.

I think you may be right about this. I have rust code that is fetching some data from a web API, then doing some slightly heavy processing (doing a few regex searches against several thousand pieces of text). My thought was to put the computational work on another isolate (which is what I would do if it were pure Dart), but after posting this issue, I found the Asynchronous Dart page in the docs. Is that page saying that the rust code will automatically be running in a thread that is not the same one running the main isolate? If so, then it sounds like I don't actually need the extra isolate after all, and I could just count on the rust computations running on a separate thread.

fzyzcjy commented 1 month ago

Yes. If your Rust code do heavy processing, it will not block your Dart code. For example, even if your rust code do a while(true) loop for 10 seconds, Dart UI will still be very smooth and unaffected.

msiler commented 1 month ago

Thanks for the explanation! This should solve my problem

fzyzcjy commented 1 month ago

You are welcome and happy to see it is solved!

fzyzcjy commented 1 week ago

Close since this seems to be solved, but feel free to reopen if you have any questions!