This commit is contained in:
Michiel Borkent 2020-05-25 14:21:16 +02:00
parent 0eee62b809
commit 9a70ecfd9d
2 changed files with 98 additions and 77 deletions

View file

@ -30,6 +30,9 @@
(some-> (get m k) (some-> (get m k)
bytes->string)) bytes->string))
(def callbacks
(atom {}))
(defn processor [pod] (defn processor [pod]
(let [stdout (:stdout pod) (let [stdout (:stdout pod)
format (:format pod) format (:format pod)
@ -46,59 +49,62 @@
(catch java.io.EOFException _ (catch java.io.EOFException _
::EOF))] ::EOF))]
(when-not (identical? ::EOF reply) (when-not (identical? ::EOF reply)
(let [id (get reply "id") (let [id (get reply "id")
id (bytes->string id) id (bytes->string id)]
value* (find reply "value") (if-let [cb (get @callbacks id)]
value (some-> value* (do (swap! callbacks dissoc id)
second (cb reply))
bytes->string (let [value* (find reply "value")
read-fn) value (some-> value*
status (get reply "status") second
status (set (map (comp keyword bytes->string) status)) bytes->string
error? (contains? status :error) read-fn)
done? (or error? (contains? status :done)) status (get reply "status")
[ex-message ex-data] status (set (map (comp keyword bytes->string) status))
(when error? error? (contains? status :error)
[(or (some-> (get reply "ex-message") done? (or error? (contains? status :done))
bytes->string) [ex-message ex-data]
"") (when error?
(or (some-> (get reply "ex-data") [(or (some-> (get reply "ex-message")
bytes->string bytes->string)
read-fn) "")
{})]) (or (some-> (get reply "ex-data")
chan (get @chans id) bytes->string
promise? (instance? clojure.lang.IPending chan) read-fn)
exception (when (and promise? error?) {})])
(ex-info ex-message ex-data)) chan (get @chans id)
;; NOTE: if we need more fine-grained handlers, we will add promise? (instance? clojure.lang.IPending chan)
;; a :raw handler that will just get the bencode message's raw exception (when (and promise? error?)
;; data (ex-info ex-message ex-data))
{error-handler :error ;; NOTE: if we need more fine-grained handlers, we will add
done-handler :done ;; a :raw handler that will just get the bencode message's raw
success-handler :success} (when (map? chan) ;; data
chan) {error-handler :error
out (some-> (get reply "out") done-handler :done
bytes->string) success-handler :success} (when (map? chan)
err (some-> (get reply "err") chan)
bytes->string)] out (some-> (get reply "out")
(when (or value* error?) bytes->string)
(cond promise? err (some-> (get reply "err")
(deliver chan (if error? exception value)) bytes->string)]
(and (not error?) success-handler) (when (or value* error?)
(success-handler value) (cond promise?
(and error? error-handler) (deliver chan (if error? exception value))
(error-handler {:ex-message ex-message (and (not error?) success-handler)
:ex-data ex-data}))) (success-handler value)
(when (and done? (not error?)) (and error? error-handler)
(when promise? (error-handler {:ex-message ex-message
(deliver chan nil)) :ex-data ex-data})))
(when done-handler (when (and done? (not error?))
(done-handler))) (when promise?
(when out (deliver chan nil))
(binding [*out* out-stream] (when done-handler
(println out))) (done-handler)))
(when err (binding [*out* err-stream] (when out
(println err)))) (binding [*out* out-stream]
(println out)))
(when err (binding [*out* err-stream]
(println err))))))
(recur)))) (recur))))
(catch Exception e (catch Exception e
(binding [*out* *err* #_err-stream] (binding [*out* *err* #_err-stream]
@ -161,6 +167,30 @@
dict-vals (map (comp resolve-fn bytes->symbol) (vals dict))] dict-vals (map (comp resolve-fn bytes->symbol) (vals dict))]
(zipmap dict-keys dict-vals)))) (zipmap dict-keys dict-vals))))
(defn bencode->vars [pod ns-name-str vars]
(mapv
(fn [var]
(let [name (get-string var "name")
async? (some-> (get var "async")
bytes->string
#(Boolean/parseBoolean %))
name-sym (symbol name)
sym (symbol ns-name-str name)
code (get-maybe-string var "code")]
[name-sym
(or code
(fn [& args]
(let [res (invoke pod sym args {:async async?})]
res)))]))
vars))
(defn bencode->namespace [pod namespace]
(let [name-str (-> namespace (get "name") bytes->string)
name-sym (symbol name-str)
vars (get namespace "vars")
vars (bencode->vars pod name-str vars)]
[name-sym vars]))
(defn load-pod (defn load-pod
([pod-spec] (load-pod pod-spec nil)) ([pod-spec] (load-pod pod-spec nil))
([pod-spec {:keys [:remove-ns :resolve]}] ([pod-spec {:keys [:remove-ns :resolve]}]
@ -197,33 +227,23 @@
(get-string ns "name")) (get-string ns "name"))
(next-id)) (next-id))
pod (assoc pod :pod-id pod-id) pod (assoc pod :pod-id pod-id)
vars-fn (fn [ns-name-str vars] pod-namespaces (mapv #(bencode->namespace pod %)
(mapv
(fn [var]
(let [name (get-string var "name")
async? (some-> (get var "async")
bytes->string
#(Boolean/parseBoolean %))
name-sym (symbol name)
sym (symbol ns-name-str name)
code (get-maybe-string var "code")]
[name-sym
(or code
(fn [& args]
(let [res (invoke pod sym args {:async async?})]
res)))]))
vars))
pod-namespaces (mapv (fn [namespace]
(let [name-str (-> namespace (get "name") bytes->string)
name-sym (symbol name-str)
vars (get namespace "vars")
vars (vars-fn name-str vars)]
[name-sym vars]))
pod-namespaces) pod-namespaces)
pod (assoc pod :namespaces pod-namespaces)] pod (assoc pod :namespaces pod-namespaces)]
(swap! pods assoc pod-id pod) (swap! pods assoc pod-id pod)
pod))) pod)))
(defn load-ns [pod namespace callback]
(let [id (next-id)
callback (fn [reply]
(let [namespace (bencode->namespace pod reply)]
(callback namespace)))]
(swap! callbacks assoc id callback)
(write (:stdin pod)
{"op" "load"
"path" (str namespace)
"id" 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)]
(invoke pod fn-sym args opts))) (invoke pod fn-sym args opts)))

View file

@ -47,8 +47,9 @@
(when (seq namespaces-to-load) (when (seq namespaces-to-load)
(let [load-fn (fn load-fn [{:keys [:namespace]}] (let [load-fn (fn load-fn [{:keys [:namespace]}]
(when (contains? namespaces-to-load namespace) (when (contains? namespaces-to-load namespace)
#_(impl/load pod namespace (fn [namespace] (impl/load-ns
(process-namespace ctx namespace))) pod namespace (fn [namespace]
(process-namespace ctx namespace)))
"")) ""))
prev-load-fn (:load-fn @env) prev-load-fn (:load-fn @env)
new-load-fn (fn [m] new-load-fn (fn [m]