[#3] unload-pod

This commit is contained in:
Michiel Borkent 2020-05-20 20:11:46 +02:00 committed by GitHub
parent 990d804199
commit 3e5637b33f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 165 additions and 118 deletions

View file

@ -5,5 +5,9 @@
([pod-spec] (load-pod pod-spec nil)) ([pod-spec] (load-pod pod-spec nil))
([pod-spec opts] (jvm/load-pod pod-spec opts))) ([pod-spec opts] (jvm/load-pod pod-spec opts)))
(defn unload-pod
([pod-id] (unload-pod pod-id {}))
([pod-id opts] (jvm/unload-pod pod-id opts)))
(defn invoke [pod-id sym args opts] (defn invoke [pod-id sym args opts]
(jvm/invoke pod-id sym args opts)) (jvm/invoke pod-id sym args opts))

View file

@ -128,9 +128,24 @@
(def pods (atom {})) (def pods (atom {}))
(defn lookup-pod [pod-id]
(get @pods pod-id))
(defn destroy [pod-id]
(when-let [pod (lookup-pod pod-id)]
(if (contains? (:ops pod) :shutdown)
(do (write (:stdin pod)
{"op" "shutdown"
"id" (next-id)})
(.waitFor ^Process (:process pod)))
(.destroy ^Process (:process pod)))
(when-let [rns (:remove-ns pod)]
(doseq [[ns-name _] (:namespaces pod)]
(rns ns-name)))))
(defn load-pod (defn load-pod
([pod-spec] (load-pod pod-spec nil)) ([pod-spec] (load-pod pod-spec nil))
([pod-spec _opts] ([pod-spec {:keys [:remove-ns]}]
(let [pod-spec (if (string? pod-spec) [pod-spec] pod-spec) (let [pod-spec (if (string? pod-spec) [pod-spec] pod-spec)
pb (ProcessBuilder. ^java.util.List pod-spec) pb (ProcessBuilder. ^java.util.List pod-spec)
_ (.redirectError pb java.lang.ProcessBuilder$Redirect/INHERIT) _ (.redirectError pb java.lang.ProcessBuilder$Redirect/INHERIT)
@ -154,14 +169,9 @@
:format format :format format
:ops ops :ops ops
:out *out* :out *out*
:err *err*} :err *err*
_ (add-shutdown-hook! :remove-ns remove-ns}
(fn [] _ (add-shutdown-hook! #(destroy pod))
(if (contains? ops :shutdown)
(do (write stdin {"op" "shutdown"
"id" (next-id)})
(.waitFor p))
(.destroy p))))
pod-namespaces (get reply "namespaces") pod-namespaces (get reply "namespaces")
pod-id (or pod-id (when-let [ns (first pod-namespaces)] pod-id (or pod-id (when-let [ns (first pod-namespaces)]
(get-string ns "name"))) (get-string ns "name")))
@ -195,9 +205,10 @@
(swap! pods assoc pod-id pod) (swap! pods assoc pod-id pod)
pod))) pod)))
(defn lookup-pod [pod-id]
(get @pods pod-id))
(defn invoke-public [pod-id fn-sym args opts] (defn invoke-public [pod-id fn-sym args opts]
(let [pod (lookup-pod pod-id)] (let [pod (lookup-pod pod-id)]
{:result (invoke pod fn-sym args opts)})) (invoke pod fn-sym args opts)
nil))
(defn unload-pod [pod-id]
(destroy pod-id))

View file

@ -4,7 +4,7 @@
(defn load-pod (defn load-pod
([pod-spec] (load-pod pod-spec nil)) ([pod-spec] (load-pod pod-spec nil))
([pod-spec _opts] ([pod-spec _opts]
(let [pod (impl/load-pod pod-spec _opts) (let [pod (impl/load-pod pod-spec {:remove-ns remove-ns})
namespaces (:namespaces pod)] namespaces (:namespaces pod)]
(doseq [[ns-sym v] namespaces] (doseq [[ns-sym v] namespaces]
(binding [*ns* (load-string (format "(ns %s) *ns*" ns-sym))] (binding [*ns* (load-string (format "(ns %s) *ns*" ns-sym))]
@ -17,7 +17,12 @@
(string? v) (string? v)
(load-string v))))) (load-string v)))))
(future (impl/processor pod)) (future (impl/processor pod))
nil))) (:pod-id pod))))
(defn unload-pod
([pod-id] (unload-pod pod-id {}))
([pod-id _opts]
(impl/unload-pod pod-id)))
(defn invoke [pod-id sym args opts] (defn invoke [pod-id sym args opts]
(impl/invoke-public pod-id sym args opts)) (impl/invoke-public pod-id sym args opts))

View file

@ -7,11 +7,14 @@
(fn (fn
([ctx pod-spec] (load-pod ctx pod-spec nil)) ([ctx pod-spec] (load-pod ctx pod-spec nil))
([ctx pod-spec _opts] ([ctx pod-spec _opts]
(let [pod (binding [*out* @sci/out (let [env (:env ctx)
pod (binding [*out* @sci/out
*err* @sci/err] *err* @sci/err]
(impl/load-pod pod-spec _opts)) (impl/load-pod pod-spec
namespaces (:namespaces pod) {:remove-ns
env (:env ctx)] (fn [sym]
(swap! env update :namespaces dissoc sym))}))
namespaces (:namespaces pod)]
(doseq [[ns-name vars] namespaces (doseq [[ns-name vars] namespaces
:let [sci-ns (sci/create-ns ns-name)]] :let [sci-ns (sci/create-ns ns-name)]]
(sci/binding [sci/ns sci-ns] (sci/binding [sci/ns sci-ns]
@ -21,8 +24,13 @@
(string? var-value) (string? var-value)
(sci/eval-string* ctx var-value))))) (sci/eval-string* ctx var-value)))))
(sci/future (impl/processor pod)) (sci/future (impl/processor pod))
nil))) (:pod-id pod))))
{:sci.impl/op :needs-ctx})) {:sci.impl/op :needs-ctx}))
(defn unload-pod
([pod-id] (unload-pod pod-id {}))
([pod-id _opts]
(impl/unload-pod pod-id)))
(defn invoke [pod-id sym args opts] (defn invoke [pod-id sym args opts]
(impl/invoke-public pod-id sym args opts)) (impl/invoke-public pod-id sym args opts))

View file

@ -36,6 +36,7 @@
read-fn (if (identical? :json format) read-fn (if (identical? :json format)
#(cheshire/parse-string % true) #(cheshire/parse-string % true)
edn/read-string)] edn/read-string)]
(try
(loop [] (loop []
(let [message (try (read) (let [message (try (read)
(catch java.io.EOFException _ (catch java.io.EOFException _
@ -126,7 +127,10 @@
"id" id "id" id
"value" "nil"})) "value" "nil"}))
(recur)) (recur))
:shutdown (System/exit 0)))))))) :shutdown (System/exit 0))))))
(catch Exception e
(binding [*out* *err*]
(prn e))))))
(defn -main [& args] (defn -main [& args]
(when (= "true" (System/getenv "BABASHKA_POD")) (when (= "true" (System/getenv "BABASHKA_POD"))

View file

@ -1,6 +1,7 @@
(require '[babashka.pods :as pods]) (require '[babashka.pods :as pods])
(prn (pods/load-pod ["clojure" "-A:test-pod"])) ;; should return nil (def pod-id (pods/load-pod ["clojure" "-A:test-pod"]))
(require '[pod.test-pod :as pod]) (require '[pod.test-pod :as pod])
(def pod-ns-name (ns-name (find-ns 'pod.test-pod)))
(def stream-results (atom [])) (def stream-results (atom []))
(def done-prom (promise)) (def done-prom (promise))
@ -33,11 +34,21 @@
{:error (fn [m] {:error (fn [m]
(deliver error-result m))}}) (deliver error-result m))}})
[(pod/assoc {:a 1} :b 2) (def assoc-result (pod/assoc {:a 1} :b 2))
(pod.test-pod/add-sync 1 2 3) (def add-result (pod.test-pod/add-sync 1 2 3))
(def nil-result (pod.test-pod/return-nil))
(pods/unload-pod pod-id)
(def successfully-removed (nil? (find-ns 'pod.test-pod)))
[pod-id
pod-ns-name
assoc-result
add-result
@stream-results @stream-results
ex-result ex-result
(pod.test-pod/return-nil) nil-result
@callback-result @callback-result
(:ex-message @error-result) (:ex-message @error-result)
(:ex-data @error-result)] (:ex-data @error-result)
successfully-removed]

View file

@ -13,5 +13,6 @@
test-program test-program
{:namespaces {'babashka.pods {:namespaces {'babashka.pods
{'load-pod pods/load-pod {'load-pod pods/load-pod
'invoke pods/invoke}}}))] 'invoke pods/invoke
'unload-pod pods/unload-pod}}}))]
(assertions out err ret))) (assertions out err ret)))

View file

@ -5,13 +5,16 @@
(def test-program (slurp (io/file "test-resources" "test_program.clj"))) (def test-program (slurp (io/file "test-resources" "test_program.clj")))
(defn assertions [out err ret] (defn assertions [out err ret]
(is (= '[{:a 1, :b 2} (is (= '["pod.test-pod"
pod.test-pod
{:a 1, :b 2}
6 6
[1 2 3 4 5 6 7 8 9] [1 2 3 4 5 6 7 8 9]
"Illegal arguments / {:args (1 2 3)}" "Illegal arguments / {:args (1 2 3)}"
nil nil
3 3
"java.lang.String cannot be cast to java.lang.Number" "java.lang.String cannot be cast to java.lang.Number"
{:args ["1" 2]}] ret)) {:args ["1" 2]}
(is (= "nil\n(\"hello\" \"print\" \"this\" \"debugging\" \"message\")\n:foo\n:foo\n" (str out))) true] ret))
(is (= "(\"hello\" \"print\" \"this\" \"debugging\" \"message\")\n:foo\n:foo\n" (str out)))
(is (= "(\"hello\" \"print\" \"this\" \"error\")\n" (str err)))) (is (= "(\"hello\" \"print\" \"this\" \"error\")\n" (str err))))