diff --git a/CHANGELOG.md b/CHANGELOG.md index a751a8f..741e924 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +- #61: add transit as explicit JVM dependency +- #60: transform pod reader error into exception of caller +- Switch "out" and "err" messages to print and flush instead of `println` (@justone) +- Set TCP_NODELAY on transport socket (@retrogradeorbit) +- Allow env vars OS_NAME & OS_ARCH to override os props (@cap10morgan) - #49: don't log socket closed exception ## ... diff --git a/project.clj b/project.clj index 58fbd99..cfd8d90 100644 --- a/project.clj +++ b/project.clj @@ -8,7 +8,8 @@ :dependencies [[org.clojure/clojure "1.10.3"] [nrepl/bencode "1.1.0"] [cheshire "5.10.0"] - [babashka/fs "0.1.6"]] + [babashka/fs "0.1.6"] + [com.cognitect/transit-clj "1.0.329"]] :deploy-repositories [["clojars" {:url "https://clojars.org/repo" :username :env/clojars_user :password :env/clojars_pass diff --git a/src/babashka/pods/impl.clj b/src/babashka/pods/impl.clj index eded61e..f1f0f55 100644 --- a/src/babashka/pods/impl.clj +++ b/src/babashka/pods/impl.clj @@ -177,14 +177,17 @@ (let [id (get reply "id") id (bytes->string id) value* (find reply "value") - value (some-> value* - second - bytes->string - read-fn) + [exception value] (try (some->> value* + second + bytes->string + read-fn + (vector nil)) + (catch Exception e + [e nil])) status (get reply "status") status (set (map (comp keyword bytes->string) status)) - error? (contains? status :error) - done? (or error? (contains? status :done)) + error? (or exception (contains? status :error)) + done? (or error? exception (contains? status :done)) [ex-message ex-data] (when error? [(or (some-> (get reply "ex-message") @@ -202,8 +205,9 @@ :vars (bencode->vars pod name-str v)})) chan (get @chans id) promise? (instance? clojure.lang.IPending chan) - exception (when (and promise? error?) - (ex-info ex-message ex-data)) + exception (or exception + (when (and promise? error?) + (ex-info ex-message ex-data))) ;; NOTE: if we need more fine-grained handlers, we will add ;; a :raw handler that will just get the bencode message's raw ;; data @@ -350,7 +354,7 @@ (.redirectError pb java.lang.ProcessBuilder$Redirect/INHERIT)) _ (cond-> (doto (.environment pb) (.put "BABASHKA_POD" "true")) - socket? (.put "BABASHKA_POD_TRANSPORT" "socket")) + socket? (.put "BABASHKA_POD_TRANSPORT" "socket")) p (.start pb) port-file (when socket? (port-file (.pid p))) socket-port (when socket? (read-port port-file)) diff --git a/test-pod/pod/test_pod.clj b/test-pod/pod/test_pod.clj index 7fb8506..3fb5b5c 100644 --- a/test-pod/pod/test_pod.clj +++ b/test-pod/pod/test_pod.clj @@ -151,7 +151,8 @@ (babashka.pods/add-transit-read-handler! \"java.array\" into-array) -"}] +"} + {"name" "incorrect-edn"}] dependents)} {"name" "pod.test-pod.loaded" "defer" "true"} @@ -238,7 +239,12 @@ (write out {"status" ["done"] "id" id - "value" (write-fn (first args))})) + "value" (write-fn (first args))}) + pod.test-pod/incorrect-edn + (write out + {"status" ["done"] + "id" id + "value" (write-fn {(keyword "foo bar") 1})})) (recur)) :shutdown (System/exit 0) :load-ns (let [ns (-> (get message "ns") diff --git a/test-resources/test_program.clj b/test-resources/test_program.clj index de22ce3..476b062 100644 --- a/test-resources/test_program.clj +++ b/test-resources/test_program.clj @@ -90,6 +90,10 @@ (require '[pod.test-pod.loaded2 :as loaded2]) (def loaded (loaded2/loaded 1)) +(def incorrect-edn-response + (try (pod.test-pod/incorrect-edn) + (catch Exception e (ex-message e)))) + (pods/unload-pod pod-id) (def successfully-removed (nil? (find-ns 'pod.test-pod))) @@ -115,4 +119,5 @@ should-be-1 add-sync-meta error-meta - read-other-tag-meta] + read-other-tag-meta + incorrect-edn-response] diff --git a/test/babashka/pods/jvm_test.clj b/test/babashka/pods/jvm_test.clj index fae2e43..1f8c4b4 100644 --- a/test/babashka/pods/jvm_test.clj +++ b/test/babashka/pods/jvm_test.clj @@ -19,7 +19,7 @@ (let [out (java.io.StringWriter.) err (java.io.StringWriter.) ex (binding [*out* out - *err* err] + *err* err] (try (load-string pod-registry) (catch Exception e diff --git a/test/babashka/pods/sci_test.clj b/test/babashka/pods/sci_test.clj index 793882b..88121d3 100644 --- a/test/babashka/pods/sci_test.clj +++ b/test/babashka/pods/sci_test.clj @@ -23,7 +23,9 @@ _ (vreset! ctx-ref ctx) ret (sci/binding [sci/out out sci/err err] - (sci/eval-string* ctx test-program))] + (binding [*out* out + *err* err] + (sci/eval-string* ctx test-program)))] (assertions out err ret))) (deftest pod-registry-test diff --git a/test/babashka/pods/test_common.clj b/test/babashka/pods/test_common.clj index ad4a1eb..3a793b4 100644 --- a/test/babashka/pods/test_common.clj +++ b/test/babashka/pods/test_common.clj @@ -1,5 +1,6 @@ (ns babashka.pods.test-common (:require [clojure.java.io :as io] + [clojure.string :as str] [clojure.test :refer [is]])) (def test-program (slurp (io/file "test-resources" "test_program.clj"))) @@ -9,34 +10,42 @@ ;; (.println System/err out) ;; (.println System/err err) (doseq [[expected actual] - (map vector '["pod.test-pod" - pod.test-pod - {:a 1, :b 2} - 6 - 3 - [1 2 3 4 5 6 7 8 9] - #"Illegal arguments / \{:args [\(\[]1 2 3[\)\]]\}" - nil - 3 - #"cast" - {:args ["1" 2]} - true - 9 - [1 2 3] - [[1] [1]] - 2 - 3 - true ;; local-date - true ;; roundtrip string array - 1 - "add the arguments" - nil - nil] + (map vector (replace + {::edn-error (if (= "edn" + (System/getenv "BABASHKA_POD_TEST_FORMAT")) + "Map literal must contain an even number of forms" + ::dont-care)} + '["pod.test-pod" + pod.test-pod + {:a 1, :b 2} + 6 + 3 + [1 2 3 4 5 6 7 8 9] + #"Illegal arguments / \{:args [\(\[]1 2 3[\)\]]\}" + nil + 3 + #"cast" + {:args ["1" 2]} + true + 9 + [1 2 3] + [[1] [1]] + 2 + 3 + true ;; local-date + true ;; roundtrip string array + 1 + "add the arguments" + nil + nil + ::edn-error]) (concat ret (repeat ::nil)))] - (if (instance? java.util.regex.Pattern expected) - (is (re-find expected actual)) - (is (= expected actual)))) + (cond (instance? java.util.regex.Pattern expected) + (is (re-find expected actual)) + (= ::dont-care expected) nil + :else + (is (= expected actual)))) (is (= "(\"hello\" \"print\" \"this\" \"debugging\" \"message\")\n:foo\n:foo\n" (str out))) - (is (= "(\"hello\" \"print\" \"this\" \"error\")\n" (str err)))) + (is (str/starts-with? (str err) "(\"hello\" \"print\" \"this\" \"error\")" ))) (def pod-registry (slurp (io/file "test-resources" "pod_registry.clj")))