Clojure - 引用 defrecord 函数

Clojure - refer to a defrecord function

如何引用记录的函数?

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

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

  (stop [component]
    ...)

但是在 README 中指出:

...you could wrap the body of stop in a try/catch that ignores all exceptions. That way, errors stopping one component will not prevent other components from shutting down cleanly.

不过,我想为此使用 Dire。现在如何引用 stop 函数与 Dire 一起使用?

你不包装 stop,你包装 stop 的主体 - 也就是说,除了参数声明之外的所有内容都包装在你的 dire/with-handler! 块中,或者任何其他错误捕获你的方法更喜欢。

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

请注意,无论您如何处理错误,如果您不从 start 方法中 return 组件,就会破坏系统。

有两个自然选项:

  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)))