首页 > 解决方案 > 启动方法后基座组件不更新自身

问题描述

我的基座组件的代码如下。当 Stuart Sierra 的库启动我的系统映射时,Pedestal defrecord 中实现的方法 start 被调用,它返回与 :pedestal-server 关联的组件的更新版本。生命周期管理器不应该传播更新的组件以便它可以被 stop 方法使用吗?每当我尝试通过在 REPL 中调用 (component/stop (system)) 来停止服务器时,什么都不会发生,因为 :pedestal-server 键设置为 nil。

(defrecord Pedestal [service-map pedestal-server]
  component/Lifecycle

 (start [this]
  (if pedestal-server
    this
    (assoc this :pedestal-server
                (-> service-map
                    http/create-server
                    http/start))))
 (stop [this]
   (when pedestal-server
     (http/stop pedestal-server))
   (assoc this :pedestal-server nil)))

(defn new-pedestal []
  (map->Pedestal {}))

标签: clojurecomponentspedestal

解决方案


您应该注意,(com.stuartsierra.component/start)在组件上调用该函数会返回组件的启动副本,但它不会修改组件本身。同样,调用(com.stuartsierra.component/stop)将返回组件的已停止副本。

我认为:pedestal-serverkey 的值为 nil ,因为您没有存储(start)调用的返回值,而是在原始(未启动的)组件上调用了它。

您需要将应用程序的状态存储在某个存储中,例如 atom 或 var。然后您可以使用start和更新存储的状态stop

例如:

;; first we create a new component and store it in system.
(def system (new-pedestal))

;; this function starts the state and saves it:
(defn start-pedestal! [] (alter-var-root #'system component/start))

;; this function stops the running state:
(defn stop-pedestal! [] (alter-var-root #'system component/stop))

推荐阅读