Clojure编译时​​间

时间:2017-12-11 14:29:15

标签: clojure compilation leiningen

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

步骤进行:

  1. lein new app testing
  2. 修改了src / testing / core.clj和project.clj(见下文)
  3. lein jar(或lein uberjar
  4. 为简单起见,我已经有了这个非常简单的代码,编译成一个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看起来非常有趣,但是如果编译这么小的程序需要几个小时,在我的情况下部署可能会成为一个问题。

1 个答案:

答案 0 :(得分:3)

当命名空间 Ahead of Time (project.clj中的:aot [testing.core])时,在编译期间会对此代码进行评估:

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

这很可能导致挂起。编译器永远不会继续,因为它已经进行了阻塞调用。

  1. 如果您不需要,可以删除:aot指令(您可能不会这样做)。我认为在创建一个新的Leiningen项目时,这可能是一个有点混乱的默认值。

  2. 您可以执行类似套接字/ conn的操作delay

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

    然后deref / @,无论您需要什么值。这只是延迟ws/connect的评估,直到你问。