gpt4 book ai didi

concurrency - 如何从 clojure future 中的错误中获取堆栈跟踪?

转载 作者:行者123 更新时间:2023-12-05 01:03:27 26 4
gpt4 key购买 nike

我有一些非常独立的任务,我已经使用 future 分拆出来。这些任务通过 core.async/chan 将某些事件传送回主应用程序,或者只是与数据库对话。

其中一些 future 正在悄然失败。我的日志或 std{out,err} 中没有任何堆栈跟踪。我试过围绕 future 调用的 fns 中的代码

(try (do-stuff)
(catch Exception e
(log/error e))

只是为了在我的日志中获得一些输出,但是——令人惊讶的是!——没有用。

我唯一的选择是启动另一个在循环中执行以下操作的线程吗?
(let [m (Thread/getAllStackTraces)]
(doseq [e (.entrySet m)]
(log/error (.toString (.getKey e)))
(doseq [s (.getValue e)]
(log/error " " (.toString s)))))

这是表明我根本不应该使用 future 的症状吗?即使不需要向这些代理发送任何消息,我是否应该使用代理?

最佳答案

该行为非常类似于 Java Future .在 future 的块中,异常可能会被抛出和捕获,这就像你期望的那样。当未捕获异常时,Future无法在调用线程上重新抛出它。它仅以 ExecutionException 的形式这样做当你真正得到它的值(value)时。这对应于 Clojure 中的 deref。

让我们创建一个抛出一些东西的函数:

(defn die [] (throw (RuntimeException.)))

如果我以后只是包装它,它就可以正常工作:
user=> (def x (future (die)))
#'user/x
; Note: No exception here
user=> @x
RuntimeException user/die (NO_SOURCE_FILE:1)
; Bam! Exception thrown on deref, think of it as
; ExecutionException when getting failed future's value in Java

所以你可以在 deref 上捕获这个异常:
user=> (def x (future (die)))
#'user/x
(try @x (catch Exception e (println "Caught ya")))
Caught ya
nil

或者你可以在 future 捕捉它:
user=> (def x 
#_=> (future
#_=> (try (die)
#_=> (catch Exception e
#_=> (print "Caught ya!")
#_=> "Something"))))
#'user/x
Caught ya
user=> @x
"Something"

请注意,在这种情况下,在取消引用之前,当后台线程上发生错误时,它如何立即打印“Caught ya”。然后在 deref 上它返回将来由 catch 块返回的值。

再一次,底线是 - 它的工作原理与 Java future 几乎相同。

关于concurrency - 如何从 clojure future 中的错误中获取堆栈跟踪?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24663771/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com