Clojure - 参考defrecord函数

时间:2015-10-31 21:45:21

标签: error-handling clojure architecture

如何引用记录功能?

对于上下文,我使用的是Stuart Sierra的组件。所以我有这样的记录:

(defrecord MyComponent []
  component/Lifecycle
  (start [component]
    ...)

  (stop [component]
    ...)

然而,在README中,声明:

  

...你可以在一个忽略所有的try / catch中包裹stop的主体   例外。这样,停止一个组件的错误将无法阻止   其他组件干净利落地关闭。

但是,我想使用Dire。现在,我如何引用stop函数与Dire一起使用?

2 个答案:

答案 0 :(得分:2)

你没有包裹stop,你包裹了停止的主体 - 也就是说,除了参数声明之外的所有内容都包含在你的dire/with-handler!块中,或者其他任何错误捕获方法偏爱。

(defstruct MyComponent []
   component/Lifecycle
   (start [component]
      (try (/ 1 0)
        (catch Exception e)
        (finally component))))

请注意,无论您处理错误,如果不从start方法返回组件,都会破坏系统。

答案 1 :(得分:2)

有两种自然选择:

  1. 您可以使用Dire来处理component/stop(可能还有start)的错误:

    (dire.core/with-handler! #'com.stuartsierra.component/stop
      …)
    

    这样您就可以承诺处理系统中可能使用的所有组件的错误,以及在应用程序的任何位置对component/stop进行的任何调用。

  2. 您可以引入一个顶级函数来处理组件的stop逻辑,使用Dire注册它并让component/stop实现仅委托给它,并且可能处理start同样地:

    (defn start-my-component [component]
      …)
    
    (defn stop-my-component [component]
      …)
    
    (dire.core/with-handler! #'start-my-component
      …)
    
    (dire.core/with-handler! #'stop-my-component
      …)
    
    (defrecord MyComponent […]
      component/Lifecycle
      (start [component]
        (start-my-component component))
    
      (stop [component]
        (stop-my-component component)))