Skip to content
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

Dart Functions aren't cancel safe #2511

Open
sampaioletti opened this issue Jan 22, 2025 · 6 comments
Open

Dart Functions aren't cancel safe #2511

sampaioletti opened this issue Jan 22, 2025 · 6 comments
Labels
awaiting Waiting for responses, PR, further discussions, upstream release, etc

Comments

@sampaioletti
Copy link

sampaioletti commented Jan 22, 2025

Sorry i was unable to use the bug template..it kept saying could not create issue.

Calling an Async Dart Fn in a cancelable context causes a panic.

Clone and modify the https://github.com/fzyzcjy/flutter_rust_bridge/tree/master/frb_example/dart_minimal example as follows.

  1. Add tokio
  2. Add rust sleep fn in rust/src/api/minimal.rs
pub async fn sleep_fn( sleep_cb: impl Fn(i32) -> DartFnFuture<()> + Send + Sync + 'static){
    tokio::select!{
        _=(sleep_cb)(1000)=>{
            println!("sleep 1000 returning")
        }
        _=(sleep_cb)(500)=>{
            println!("sleep 500 returning")
        }
    }
}
  1. Call from dart in lib/src/main.dart
  await sleepFn(sleepCb: (ms) async {
    print("sleeping $ms");
    await Future.delayed(Duration(milliseconds: ms));
    print("returning $ms");
  });

Short sleep returns first and successfully returns from select function

When longer delay returns it causes a panic..I think because the future has been dropped.

sleeping 1000
sleeping 500
returning 500
sleep 500 returning
returning 1000
thread '<unnamed>' panicked at C:\Code\playground\flutter_rust_bridge\frb_rust\src\dart_fn\handler.rs:61:45:
called `Result::unwrap()` on an `Err` value: Dart2RustMessageSse { vec: [0, 0, 0, 0, 0, 0, 0, 0], data_len: 1 }

Fork available at https://github.com/sampaioletti/flutter_rust_bridge/tree/cancel-async-bug

@fzyzcjy
Copy link
Owner

fzyzcjy commented Jan 22, 2025

Hi, could you please show full stacktrace to see what is going on? (e.g. by https://cjycode.com/flutter_rust_bridge/guides/how-to/stack-trace)

@sampaioletti
Copy link
Author

Sorry had to get setup in WSL since the backtrace in windows is junk

Call Rust and get: 100+200 = 300
sleeping 500
sleeping 1000
returinging 500
sleep 500 returning
returinging 1000
thread '<unnamed>' panicked at /mnt/c/Code/playground/flutter_rust_bridge/frb_rust/src/dart_fn/handler.rs:61:45:
called `Result::unwrap()` on an `Err` value: Dart2RustMessageSse { vec: [0, 0, 0, 0, 0, 0, 0, 0], data_len: 1 }
stack backtrace:
   0:     0x7ff36b93083a - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::ha4a311b32f6b4ad8
   1:     0x7ff36b94d943 - core::fmt::write::h1866771663f62b81
   2:     0x7ff36b92e153 - std::io::Write::write_fmt::hb549e7444823135e
   3:     0x7ff36b930682 - std::sys::backtrace::BacktraceLock::print::hddd3a9918ce29aa7
   4:     0x7ff36b9319cd - std::panicking::default_hook::{{closure}}::h791f75256b902d7d
   5:     0x7ff36b931813 - std::panicking::default_hook::h82cc572fcb0d8cd7
   6:     0x7ff36b8ee5f4 - flutter_rust_bridge::misc::panic_backtrace::PanicBacktrace::setup::{{closure}}::h375890a8d6440541
   7:     0x7ff36b932078 - std::panicking::rust_panic_with_hook::he21644cc2707f2c4
   8:     0x7ff36b931e3a - std::panicking::begin_panic_handler::{{closure}}::h42f7c414fed3cad9
   9:     0x7ff36b930d19 - std::sys::backtrace::__rust_end_short_backtrace::ha26cf5766b4e8c65
  10:     0x7ff36b931acc - rust_begin_unwind
  11:     0x7ff36b8dc1e0 - core::panicking::panic_fmt::h74866b78e934b1c0
  12:     0x7ff36b8dc5b6 - core::result::unwrap_failed::h899ed7ab2ccb8159
  13:     0x7ff36b8ecd7f - flutter_rust_bridge::dart_fn::handler::DartFnHandler::handle_output::hab78b2daa3dac4e5
  14:     0x7ff36b8e986f - frb_dart_fn_deliver_output
  15:     0x7ff3a9d0718b - <unknown>
Error when dart_fn_handle_output: Any { .. }

@sampaioletti
Copy link
Author

Looks to me like because of the dropped future the completor needs to ignore send errors

This commit fixes the issue in my code.

sampaioletti@0ef0b9d

@fzyzcjy
Copy link
Owner

fzyzcjy commented Jan 23, 2025

Looks reasonable and feel free to PR for this!

Btw, instead of ignoring the error, it may be reasonable to use log_warn_or_println to print it.

@fzyzcjy fzyzcjy added the awaiting Waiting for responses, PR, further discussions, upstream release, etc label Jan 23, 2025
@sampaioletti
Copy link
Author

Cool thanks. I'll throw a PR at this, but the more I've thought about it, it might be more 'correct' to wrap the dart fn in a CancelableOperation https://api.flutter.dev/flutter/async/CancelableOperation-class.html in a future PR so that we can also stop execution when it's dropped on the rust side.

@fzyzcjy
Copy link
Owner

fzyzcjy commented Jan 23, 2025

Looks pretty reasonable!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting Waiting for responses, PR, further discussions, upstream release, etc
Projects
None yet
Development

No branches or pull requests

2 participants