在Clojure中从异步进程捕获异常?
假设我正在异步发送电子邮件,并希望我的程序继续执行。到目前为止,我一直在使用在Clojure中从异步进程捕获异常?,clojure,Clojure,假设我正在异步发送电子邮件,并希望我的程序继续执行。到目前为止,我一直在使用futures进行此操作,但不幸的是,当电子邮件无法发送时,不会引发任何异常 我理解,取消对未来的引用将引发执行异常,但取消引用将无法解决这一点 有没有更好的方法可以在不丢失异常信息的情况下“发射并发射”?而不尝试 (def foo (future (Thread/sleep 5000) (throw (Exception. "bananas!"))
future
s进行此操作,但不幸的是,当电子邮件无法发送时,不会引发任何异常
我理解,取消对未来的引用将引发执行异常,但取消引用将无法解决这一点
有没有更好的方法可以在不丢失异常信息的情况下“发射并发射”?而不尝试
(def foo (future (Thread/sleep 5000)
(throw (Exception. "bananas!"))
(Thread/sleep 5000)))
(future-done? foo)
;=> false
(def bar (future (try (Thread/sleep 5000)
(throw (Exception. "bananas!"))
(Thread/sleep 5000)
(catch Exception e (println "Oh, " (.getMessage e))))))
(future-done? bar)
;=> false
5秒后
努力
(def foo (future (Thread/sleep 5000)
(throw (Exception. "bananas!"))
(Thread/sleep 5000)))
(future-done? foo)
;=> false
(def bar (future (try (Thread/sleep 5000)
(throw (Exception. "bananas!"))
(Thread/sleep 5000)
(catch Exception e (println "Oh, " (.getMessage e))))))
(future-done? bar)
;=> false
5秒后
为此,我将使用代理,使用处理函数处理代理操作引发的异常:
(agent initial-state :error-handler handler-fn)
有关详细信息,请参见(文档代理)
,(文档集错误处理程序!)
,(文档集错误模式!)
<代码>初始状态这里可能只是nil
,或者可能是保存一些日志数据的结构
为了方便起见,您需要一个电子邮件
功能,可与发送
一起使用(发送
,通过发送
):
如果主线程需要被通知有问题,那么它需要注意通过某个通道进行的通信。(Java队列是一种可能,的通道是另一种。)然后处理程序函数可以将消息推送到该通道上。您希望异常做什么?由于future只做它自己的事情,然后就完成了,因此未来的异常不应该停止主执行线程。如果您在future本身内部捕获到异常,您可以将其记录或尝试在该上下文中恢复。@Noises如果future正在执行的作业对主线程的正确性至关重要,则有时您可能希望停止主执行线程。快速问:初始状态的意义是什么?这是向主线程报告的吗?如果我不想报告任何事情——我只想好好睡一觉,知道我的电子邮件没有无声地失败——我需要设置代理的状态吗?代理是Clojure的引用类型之一;它们总是保持某种内在状态。如果您只使用代理异步执行副作用,而不使用任何特定的状态值,则可以将状态设置为
nil
,并让传递到send
(email
)的函数返回nil
。好的,这是有意义的。谢谢
(defn email [agent-state message] ...)