Clojure - 将组件传递给在启动或停止期间未执行的功能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Clojure - 将组件传递给在启动或停止期间未执行的功能相关的知识,希望对你有一定的参考价值。

在Stuart Sierra的组件的自述文件中,有一个函数add-user作为示例给出,但在其他任何地方都看不到:

(defn add-user [database username favorite-color]
  (execute-insert (:connection database)
    "INSERT INTO users (username, favorite_color)"
    username favorite-color))

我想它可以在Web服务器路由上执行(例如)。我毫不费力地想象usernamefavorite-colour将成为该路线的参数,因此在调用add-user时很容易获得。

我想这会产生database(例如)组件的web-server组件。但是我在确定databaseadd-user组件实例参数究竟应该来自哪里时遇到了一些麻烦。

我觉得直接访问system(即做(:database my-system-ns/system)))来检索它会破坏部分首先使用组件的目的。

例如,如果我使用基座,我可能有我的基座组件(谁有权访问数据库组件)设置此键:

::bootstrap/routes #(deref #'my-routes-ns/routes)

这将是这样的:

;; in my-routes-ns
(defroutes routes [[[ "/add-user" {:post add-user-handler} ]]])

;; same function again for clarity
(defn add-user [database username favorite-color]
  (execute-insert (:connection database)
    "INSERT INTO users (username, favorite_color)"
    username favorite-color))

;; my route handler
(defn add-user-handler [request]
  ;; How do I get access to the database component from here ?
  (add-user database "user" "red"))

如何在此示例中访问我的database组件?

答案

仅供参考,the README of component建议在一个或多个组件上创建一个闭包,

(defn app-routes
  "Returns the web handler function as a closure over the
  application component."
  [app-component]
  ;; Instead of static 'defroutes':
  (web-framework/routes
   (GET "/" request (home-page app-component request))
   (POST "/foo" request (foo-page app-component request))
   (not-found "Not Found")))

(defrecord WebServer [http-server app-component]
  component/Lifecycle
  (start [this]
    (assoc this :http-server
           (web-framework/start-http-server
             (app-routes app-component))))
  (stop [this]
    (stop-http-server http-server)
    this))

(defn web-server
  "Returns a new instance of the web server component which
  creates its handler dynamically."
  []
  (component/using (map->WebServer {})
                   [:app-component]))
另一答案

在典型的应用程序中,您可能在web-server组件上有一个component/using组件(参见database),以及与消费者可以调用以查询数据库的database组件相关的公共函数集合。

然后,web-server组件将负责设置您的请求处理程序并启动侦听器(如Jetty)。这将涉及获取database组件并将其注入您的处理程序,可能通过部分应用程序(如果您的处理程序看起来像(defn handler [database request] …),比如说),以便它可以在实际的add-user组件上调用database

请注意,根据应用程序的设计,您的设置可能与上述设置完全不符 - 例如,web-server只能通过一层或多层中间组件使用database组件。

以上是关于Clojure - 将组件传递给在启动或停止期间未执行的功能的主要内容,如果未能解决你的问题,请参考以下文章

将变量传递给在 TabBar 中调用的视图

将 int 文字传递给在 java 中采用整数的方法

oracle11g出现错误,监听服务启动后停止。某些服务未由其他服务或程序使用时将自动停止

K8S:将 runAsUser 权限传递给在容器内创建的文件

如何将 ServletRequest 传递给在 graphql-java 中执行 i/o 的 pojo

vue组件之间数据的传递