2017-12-11 35 views
1

私は初めてClojureをテストし、簡単なwebsocketクライアントアプリケーションを作成したいと考えました。私はライブラリhttps://github.com/stylefruits/gniazdoを見つけ、(lein runを使用して)作業するコードを得ました。しかし、瓶の中にコードをコンパイルする(どちらかlein jarまたはlein uberjarがあるのいずれかスタックか(〜1時間後に中止さ)年齢を取ると)Clojureコンパイル時

手順:

  1. lein new app testing
  2. 修正のsrc /テスト/コア。私が持ってきた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:lein jarを実行しているの

(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}}) 

出力:aferwards

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

と何を。これは正常な動作です(コンパイルするには時間がかかります)か、ここで何か不足していますか? Clojureは非常に興味深いようですが、コンパイルするには小さなプログラム時間がかかる場合でも、私の状況では展開が問題になる可能性があります。

+3

次のいずれかのあなたの 'testing.core'名前空間をAOTしないでください。2. 1.トップレベルかに接続しないでください。どのように接続をJARに格納するべきだと思いますか? – ClojureMostly

答えて

3

その名前空間が前もって(あなたproject.cljで:aot [testing.core])のコンパイルされている場合、このコードはコンパイル時に評価されますが:

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

これはハングを引き起こしているものと思われます。コンパイラーは、ブロッキング呼び出しを行ったので、これから移動することはありません。

  1. あなたがそれを必要としない(そしておそらくない)場合は、:aotディレクティブを削除することができます。私はこれが新しいライニンゲンプロジェクトを作成するとき、これはやや混乱するデフォルトになると思います。

  2. あなたはdelayにそのソケット/ CONNを包むような何か行うことができます:あなたが値を必要な場所

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

    そしてderef/@それを。これはちょうどの遅れの評価がws/connectになるまでお待ちください。

+0

私はそれを正しく理解しているかどうかは分かりません。ソケットの定義を表すバイトコードを作成するのではなく、AOTコンパイルが実際にコードを実行しますか?その場合、それも動作します: (defn socket [url](ws/connect url)) – Moe

+2

@Moeはい、クロージャーコードをコンパイルする唯一の方法は、それが存在する名前空間を実行することです。 – amalloy

関連する問題