Clojure 编译时间

Clojure compile time

我是第一次测试 Clojure,想编写一个简单的 websocket 客户端应用程序。我找到了库 https://github.com/stylefruits/gniazdo 并使代码可以工作(使用 lein run)。但是,将代码编译到 jar 中(使用 lein jarlein uberjar 要么被卡住要么需要很长时间(在 ~1h 后中止))

步数:

  1. lein new app testing
  2. 修改了 src/testing/core.clj 和 project.clj(见下文)
  3. lein jar(或lein uberjar

为了简单起见,我有这个非常简单的代码,它已经需要很长时间才能编译成一个 jar:

(ns testing.core
  (:gen-class))

(require '[gniazdo.core :as ws])

(def socket
    (ws/connect
            "wss://some.url.com/"))

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (ws/close socket))

project.clj:

(defproject testing "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [stylefruits/gniazdo "1.0.1"]]
  :main ^:skip-aot testing.core
  :aot [testing.core]
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}})

运行的输出lein jar:

$lein jar
Compiling testing.core
2017-12-11 14:15:14.813:INFO::main: Logging initialized @1352ms

没有任何后续。这是正常行为(编译需要很长时间)还是我在这里遗漏了什么? Clojure 看起来很有趣,但如果编译这么小的程序也需要几个小时,在我的情况下部署可能是个问题。

当该名称空间被编译时提前:aot [testing.core] 在您的 project.clj 中),此代码在编译期间被评估:

(def socket
  (ws/connect "wss://some.url.com/"))

这可能是导致挂起的原因。编译器永远不会从这里继续,因为它进行了阻塞调用。

  1. 如果不需要(您可能不需要),可以删除 :aot 指令。我认为在创建新的 Leiningen 项目时,这可能是一个有点令人困惑的默认设置。

  2. 您可以将 socket/conn 包裹在 delay:

    (def socket (delay (ws/connect "wss://some.url.com/")))
    

    然后 deref/@ 它在任何你需要值的地方。这只是 延迟 评估 ws/connect 直到你问。