Clojure Web App:如何逐步完成请求

时间:2014-06-14 20:18:59

标签: emacs clojure functional-programming

我使用以下组件继承了一个clojure应用程序:

  • Jetty服务器
  • 的Compojure

为了了解应用,我想逐步完成请求。 我使用Emacs作为我的IDE。

我可以使用任何工具或技术来完成此任务吗?

1 个答案:

答案 0 :(得分:1)

可悲的是,Clojure没有任何现成的步调试器。可以使用jdb连接到jvm并逐步执行字节码,但这不会直接反映您的Clojure代码(特别是由于懒惰之类的事情,可能导致某些代码在应用程序中的不同上下文中进行评估而不是源代码布局会引导你期待)。

尽管如此,一切都没有丢失。由于非常注重在惯用Clojure代码中使用不可移植数据和纯函数,因此可以直接捕获函数在运行时获得的输入值,以便研究和/或试验新值。例如:

在核心命名空间内,您可以定义处理程序并启动jetty,并从同一进程启动nrepl服务器:

(ns my-server.core
  (:require [ring.middleware
             [json :refer (wrap-json-params)]
             [multipart-params :refer (wrap-multipart-params)]]
...
             [clojure.tools.nrepl.server :as nrepl-server]))

...

(defn init
  []
  (when (= (System/getProperty "with_shell") "true")
    (nrepl-server/start-server :port 7888))
  (run-jetty handler :port 8080))

在命名空间中,代码服务于特定请求,您可以跟踪传入的数据,以便在repl中使用它/调查它

(ns my-ns.controllers.home)

(defonce debug (atom []))

(defn home
  [request]
  (let [in (java.util.Date.)
        response (process request)
        out (java.util.Date.)]
    (swap! debug conj {:in request :out response :fn home :timing [in out]})
    response))

然后,从repl连接中,您可以通过解析原子并查看各种输入和输出值来查询my-ns.controllers.hom / debug的状态。这可以推广到调查各种中间值的内容,无论您希望跟踪执行情况。由于数据对象通常是不可移动的,因此如果创建一个原子来存储值,则可以拥有完整的记录。请注意,通过在计算请求之前和之后创建时间戳,您可以分析请求处理函数的主体的执行情况(为了清楚起见,我已将其抽象为单个函数)。

如果您想使用基于打印的跟踪,还有像clojure.tools.trace这样的库。