简体   繁体   English

如何从 rust 中的多个线程传播错误?

[英]How to propagate errors from multiple threads in rust?

In a Rust application that is:在 Rust 应用程序中:

  • Synchronous in the sense of not using "async"在不使用“异步”的意义上同步
  • multi-threaded using std::thread使用 std::thread 的多线程
  • threads are communicating via channels线程通过通道进行通信
  • the "anyhow" crate is being used to annotate and propagate Results “无论如何”板条箱被用于注释和传播结果

I am propagating all errors up to the main thread, but I only see the Error that is hit by the main thread.我将所有错误传播到主线程,但我只看到主线程遇到的错误。 This usually happens before I join the child threads, so I don't see the actual root cause.这通常发生在我加入子线程之前,所以我看不到实际的根本原因。

What minimum-boilerplate modification can I make to see the Errors from multiple threads?我可以进行哪些最小样板修改来查看来自多个线程的错误?

(I'll put some ideas I have in answers, but I'm hoping there is something better.) (我会把我的一些想法放在答案中,但我希望有更好的东西。)

I could use my main thread only for supervising child threads, aggregate all of their Results in some kind of Vec as I join them, filter it, and write custom code to print it.我可以只使用我的主线程来监督子线程,在我加入它们时将它们的所有结果聚合到某种 Vec 中,过滤它,并编写自定义代码来打印它。

This still feels like more work than should be necessary;感觉这仍然是不必要的工作。 I'm not the first person to write a threaded rust application that handles errors.我不是第一个编写处理错误的线程 rust 应用程序的人。

I could let threads panic and "propagate the panics":我可以让线程恐慌并“传播恐慌”:

https://doc.rust-lang.org/beta/std/thread/type.Result.html https://doc.rust-lang.org/beta/std/thread/type.Result.html

But this is ugly:但这很丑陋:

  • It introduces a difference between how errors are handled in child threads vs. the main thread.它引入了子线程与主线程中错误处理方式之间的差异。
  • At every fallible call site in my original code I have to add.unwrap().在我原始代码中的每个错误调用站点,我都必须添加.unwrap()。
  • If I unwrap() every error in the child threads, I might as well not even be using Result error handling, because everything will be returning Ok() or panicking.如果我 unwrap() 子线程中的每个错误,我什至可能不使用 Result 错误处理,因为一切都会返回 Ok() 或恐慌。 If I make that transformation, then I change the signature of all my existing functions, which is also gross.如果我进行这种转换,那么我会更改所有现有函数的签名,这也很糟糕。

One option would be to upgrade the entire application to use a logging framework, and then scrape through the logs.一种选择是升级整个应用程序以使用日志框架,然后搜索日志。

This will require modifications everywhere have added an anyhow.context(), ensure,, or bail.这将需要在任何地方进行修改,添加 anyhow.context()、ensure 或 bail。 annotation, to conditionally also throw a logger error.注释,有条件地也抛出一个记录器错误。

Eventually I will want both logging/telemetry and clean teardown from propagating Results, but even then I will not want to have several lines of boilerplate for every single fallible function call.最终,我将希望记录/遥测和从传播结果中清除拆卸,但即便如此,我也不希望为每个可出错的 function 调用都有几行样板文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM