I'm testing out Clojure for the first time, and wanted to write a simple websocket client application. I've found the library https://github.com/stylefruits/gniazdo and got the code to work (using lein run
). However, compiling the code into a jar (either with lein jar
or lein uberjar
is either stuck or takes ages (aborted after ~1h))
steps:
lein new app testing
lein jar
(or lein uberjar
)For simplicity I've have this very simple code, which already takes ages to compile into a 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}})
output of running lein jar
:
$lein jar
Compiling testing.core
2017-12-11 14:15:14.813:INFO::main: Logging initialized @1352ms
and nothing aferwards. Is this normal behaviour (and it just takes ages to compile) or am I missing something here? Clojure looks very interesting, but if it takes even for such a small program hours to compile, deployment could be a problem in my circumstances.
When that namespace is compiled Ahead of Time (:aot [testing.core]
in your project.clj), this code gets evaluated during compilation:
(def socket
(ws/connect "wss://some.url.com/"))
This is likely what's causing the hang. The compiler never moves on from this because it has made a blocking call.
You could remove the :aot
directive if you don't need it (and you probably don't). I think this can be a somewhat confusing default when creating a new Leiningen project.
You could do something like wrap that socket/conn in a delay
:
(def socket (delay (ws/connect "wss://some.url.com/")))
And then deref
/@
it wherever you need the value. This just delays evaluation of ws/connect
until you ask.