fzyzcjy / flutter_rust_bridge

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

Async Rust to Dart Stream Conversion Issue #1874

Closed 7reax closed 1 month ago

7reax commented 1 month ago

Describe the bug

For synchronous Rust methods returning a stream, the Dart code generation in works correctly, providing a Stream<String>. However, with the recent update, when Rust methods are async and should return a stream, the Dart code generation produces a Future<Stream<String>>. This leads to all stream elements being emitted at once after the async Rust method completes.

Steps to reproduce

  1. Create an asynchronous Rust method that is intended to return a stream of strings. For example:
    pub async fn lsx_get_event_stream(pid: u32, game_sink: StreamSink<String>) -> anyhow::Result<()>  {
    // code
    }
  2. Generate the Dart bindings.
  3. Attempt to use the generated Dart method expecting a stream of strings to be processed as they are send. Instead, find that the stream only starts emitting values after the entire async Rust method has completed execution.

Logs

-

Expected behavior

No response

Generated binding code

No response

OS

No response

Version of flutter_rust_bridge_codegen

2.0.0-dev.31

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

Hi, could you please check https://github.com/fzyzcjy/flutter_rust_bridge/issues/1873 - does that solve your scenario?

fzyzcjy commented 1 month ago

Also related #1836, cc @uditrugman

fzyzcjy commented 1 month ago

Brainstorms: one solution may be that, we by default use the old semantics, and at the same time allow #[frb(dart_async)] (which creates the semantics today) and #[frb(sync)].

7reax commented 1 month ago

Hi, could you please check #1873 - does that solve your scenario?

Correct me if I'm wrong, but it looks like this thread pool would escape the tokio runtime. We need to be able to use async functions while pushing to the stream, is that still possible?

fzyzcjy commented 1 month ago

Hmm, then does tokio::spawn (instead of thread pool spawn) work for you?

fzyzcjy commented 1 month ago

@fzyzcjy Brainstorms: one solution may be that, we by default use the old semantics, and at the same time allow #[frb(dart_async)] (which creates the semantics today) and #[frb(sync)] (which gives the semantics in https://github.com/fzyzcjy/flutter_rust_bridge/issues/1836#issuecomment-2020626894).

@uditrugman (https://github.com/fzyzcjy/flutter_rust_bridge/issues/1836#issuecomment-2020626894) - what do you think about this?

7reax commented 1 month ago

Hmm, then does tokio::spawn (instead of thread pool spawn) work for you?

Yeah, tokio::spawn works for us. Thanks!

fzyzcjy commented 1 month ago

You are welcome!

In addition, you want wait for the next release, since in #1877 I revert the default semantics. (But you can still have today's semantics via a simple #[frb(...)] annotation)

github-actions[bot] commented 3 weeks ago

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new issue.