基座组件在启动方法后未更新自身

时间:2018-08-16 17:56:40

标签: clojure components pedestal

我的Pedestal组件具有以下代码。当Stuart Sierra的库启动我的系统映射时,将调用在Pedestal defrecord中实现的start方法,并返回与:pedestal-server相关联的组件的更新版本。生命周期管理器是否应该传播已更新的组件,以便stop方法可以使用它?每当我尝试通过在REPL中调用(组件/停止(系统))来停止服务器时,都不会发生任何事情,因为: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 {}))

1 个答案:

答案 0 :(得分:1)

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

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

您需要将应用程序的状态存储在某个存储中,例如原子或变量。然后,您可以使用startstop更新存储的状态。

例如:

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