tikv / fail-rs

Fail points for rust
Apache License 2.0
332 stars 39 forks source link

Support async return #58

Open waynexia opened 2 years ago

waynexia commented 2 years ago

Support for defining fail points with async blocks. E.g.:

  async fn async_fn() {
      fail_point!("async_return", |s| async {
          (async {}).await;
          s.map_or(2, |s| s.parse().unwrap())
      });
  }
BusyJay commented 2 years ago

Interesting. What if user wants async move {}?

waynexia commented 2 years ago

Sorry for the late reply :P

For move before the closure param list, we can match it with ident. But I can't figure out how to match those after async. Here I use another rule to handle this. Please let me know if there is a better approach!

BusyJay commented 2 years ago

How about:

    ($name:expr, await $e:expr) => {{
        if let Some(res) = $crate::eval($name, $e) {
            return res.await;
        }
    }};

The rule is simple. And it matches all cases without depending on the appearance of any keywords in the expression. One drawback is it moves await ahead, which is opposite to the syntax of await.

BusyJay commented 2 years ago

/cc @brson @lucab @sticnarf I also would like to hear your advice.

waynexia commented 2 years ago

It is a good point to make the rules simple by not following the formal grammar. Wondering what others think.

lucab commented 2 years ago

Speaking of async, I do wonder whether it makes sense to have a dedicated async_fail_point!() instead. I currently see a mismatch with actions like sleep and yield in an async context, which will block the executor instead of behaving more gracefully. I'm not really a macro expert, but perhaps the implementation could end up being easier if we clearly split the sync-vs-async domains through different macros?

waynexia commented 10 months ago

I defined a new macro async_fail_point as @lucab said. It does make things more straightforward 👍 PTAL @BusyJay @lucab