nREPL server cleanup
This commit is contained in:
parent
dc68b5fa4f
commit
7e30c40dd9
2 changed files with 35 additions and 68 deletions
|
|
@ -17,10 +17,8 @@
|
|||
|
||||
(defn response-for [old-msg msg]
|
||||
(let [session (get old-msg :session "none")
|
||||
m (assoc msg "session" session)
|
||||
id (get old-msg :id "unknown")
|
||||
m (assoc m "id" id)]
|
||||
m))
|
||||
id (get old-msg :id "unknown")]
|
||||
(assoc msg "session" session "id" id)))
|
||||
|
||||
(defn send [^OutputStream os msg]
|
||||
;;(when @dev? (prn "Sending" msg))
|
||||
|
|
@ -38,7 +36,7 @@
|
|||
"status" #{"eval-error"}}))
|
||||
(send os (response-for msg {"status" #{"done"}}))))
|
||||
|
||||
(defn eval-msg [ctx o msg #_threads]
|
||||
(defn eval-msg [ctx o msg]
|
||||
(try
|
||||
(let [ns-str (get msg :ns)
|
||||
sci-ns (when ns-str (sci-utils/namespace-object (:env ctx) (symbol ns-str) true nil))
|
||||
|
|
@ -46,32 +44,27 @@
|
|||
(sci/with-bindings (cond-> {sci/out sw}
|
||||
sci-ns (assoc vars/current-ns sci-ns))
|
||||
(when @dev? (println "current ns" (vars/current-ns-name)))
|
||||
(let [session (get msg :session "none")
|
||||
id (get msg :id "unknown")]
|
||||
(when @dev? (println "Registering thread for" (str session "-" id)))
|
||||
;; (swap! threads assoc [session id] (Thread/currentThread))
|
||||
(let [code-str (get msg :code)
|
||||
value (if (str/blank? code-str)
|
||||
::nil
|
||||
(eval-string* ctx code-str))
|
||||
out-str (not-empty (str sw))
|
||||
env (:env ctx)]
|
||||
(swap! env update-in [:namespaces 'clojure.core]
|
||||
(fn [core]
|
||||
(assoc core
|
||||
'*1 value
|
||||
'*2 (get core '*1)
|
||||
'*3 (get core '*2))))
|
||||
(when @dev? (println "out str:" out-str))
|
||||
(when out-str
|
||||
(send o (response-for msg {"out" out-str})))
|
||||
(send o (response-for msg (cond-> {"ns" (vars/current-ns-name)}
|
||||
(not (identical? value ::nil)) (assoc "value" (pr-str value)))))
|
||||
(send o (response-for msg {"status" #{"done"}}))))))
|
||||
(let [code-str (get msg :code)
|
||||
value (if (str/blank? code-str)
|
||||
::nil
|
||||
(eval-string* ctx code-str))
|
||||
out-str (not-empty (str sw))
|
||||
env (:env ctx)]
|
||||
(swap! env update-in [:namespaces 'clojure.core]
|
||||
(fn [core]
|
||||
(assoc core
|
||||
'*1 value
|
||||
'*2 (get core '*1)
|
||||
'*3 (get core '*2))))
|
||||
(when @dev? (println "out str:" out-str))
|
||||
(when out-str
|
||||
(send o (response-for msg {"out" out-str})))
|
||||
(send o (response-for msg (cond-> {"ns" (vars/current-ns-name)}
|
||||
(not (identical? value ::nil)) (assoc "value" (pr-str value)))))
|
||||
(send o (response-for msg {"status" #{"done"}})))))
|
||||
(catch Exception ex
|
||||
(swap! (:env ctx) update-in [:namespaces 'clojure.core]
|
||||
(fn [core]
|
||||
(assoc core '*e ex)))
|
||||
assoc '*e ex)
|
||||
(send-exception o msg ex))))
|
||||
|
||||
(defn fully-qualified-syms [ctx ns-sym]
|
||||
|
|
@ -127,17 +120,6 @@
|
|||
(send o (response-for msg {"completions" []
|
||||
"status" #{"done"}})))))
|
||||
|
||||
;; GraalVM doesn't support the .stop method on Threads, so for now we will have to live without interrupt
|
||||
#_(defn interrupt [_ctx os msg threads]
|
||||
(let [session (get msg :session "none")
|
||||
id (get msg :interrupt-id)]
|
||||
(when-let [t (get @threads [session id])]
|
||||
(when @dev? (println "Killing thread" (str session "-" id)))
|
||||
(try (.stop ^java.lang.Thread t)
|
||||
(catch Throwable e
|
||||
(println e))))
|
||||
(send os (response-for msg {"status" #{"done"}}))))
|
||||
|
||||
(defn read-msg [msg]
|
||||
(-> (zipmap (map keyword (keys msg))
|
||||
(map #(if (bytes? %)
|
||||
|
|
@ -145,7 +127,7 @@
|
|||
%) (vals msg)))
|
||||
(update :op keyword)))
|
||||
|
||||
(defn session-loop [ctx ^InputStream is os id #_threads]
|
||||
(defn session-loop [ctx ^InputStream is os id]
|
||||
(when @dev? (println "Reading!" id (.available is)))
|
||||
(when-let [msg (try (read-bencode is)
|
||||
(catch EOFException _
|
||||
|
|
@ -157,57 +139,43 @@
|
|||
(when @dev? (println "Cloning!"))
|
||||
(let [id (str (java.util.UUID/randomUUID))]
|
||||
(send os (response-for msg {"new-session" id "status" #{"done"}}))
|
||||
(recur ctx is os id #_threads)))
|
||||
(recur ctx is os id)))
|
||||
:eval (do
|
||||
(eval-msg ctx os msg #_threads)
|
||||
(recur ctx is os id #_threads))
|
||||
(eval-msg ctx os msg)
|
||||
(recur ctx is os id))
|
||||
:load-file (let [file (:file msg)
|
||||
msg (assoc msg :code file)]
|
||||
(eval-msg ctx os msg #_threads)
|
||||
(recur ctx is os id #_threads))
|
||||
(eval-msg ctx os msg)
|
||||
(recur ctx is os id))
|
||||
:complete (do
|
||||
(complete ctx os msg)
|
||||
(recur ctx is os id #_threads))
|
||||
;; :interrupt (do
|
||||
;; (interrupt ctx os msg threads)
|
||||
;; (recur ctx is os id threads))
|
||||
(recur ctx is os id))
|
||||
:describe
|
||||
(do (send os (response-for msg {"status" #{"done"}
|
||||
"aux" {}
|
||||
"ops" (zipmap #{"clone" "eval" "load-file" "complete" "describe"}
|
||||
(repeat {}))
|
||||
"versions" {} #_{"nrepl" {"major" "0"
|
||||
"minor" "4"
|
||||
"incremental" "0"
|
||||
"qualifier" ""}
|
||||
"clojure"
|
||||
{"*clojure-version*"
|
||||
(zipmap (map name (keys *clojure-version*))
|
||||
(vals *clojure-version*))}}}))
|
||||
(recur ctx is os id #_threads))
|
||||
(repeat {}))}))
|
||||
(recur ctx is os id))
|
||||
;; fallback
|
||||
(do (when @dev?
|
||||
(println "Unhandled message" msg))
|
||||
(send os (response-for msg {"status" #{"error" "unknown-op" "done"}}))
|
||||
(recur ctx is os id #_threads))))))
|
||||
(recur ctx is os id))))))
|
||||
|
||||
(defn listen [ctx ^ServerSocket listener]
|
||||
(when @dev? (println "Listening"))
|
||||
(let [client-socket (.accept listener)
|
||||
in (.getInputStream client-socket)
|
||||
in (PushbackInputStream. in)
|
||||
out (.getOutputStream client-socket)
|
||||
#_threads #_(atom {})]
|
||||
out (.getOutputStream client-socket)]
|
||||
(when @dev? (println "Connected."))
|
||||
(sci/future
|
||||
(sci/binding
|
||||
;; allow *ns* to be set! inside future
|
||||
[vars/current-ns (vars/->SciNamespace 'user nil)
|
||||
sci/print-length @sci/print-length]
|
||||
(session-loop ctx in out "pre-init" #_threads)))
|
||||
(session-loop ctx in out "pre-init")))
|
||||
(recur ctx listener)))
|
||||
|
||||
|
||||
(def server (atom nil))
|
||||
|
||||
(defn stop-server! []
|
||||
|
|
@ -224,7 +192,6 @@
|
|||
(Integer. ^String (second parts))])
|
||||
host+port (if-not address (str "localhost:" port)
|
||||
host+port)]
|
||||
#_(complete ctx nil {:symbol "json"})
|
||||
(println "Starting nREPL server at" host+port)
|
||||
(let [socket-server (new ServerSocket port 0 address)]
|
||||
(reset! server socket-server)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
(io/copy in bout :encoding enc)
|
||||
(.toString bout))))
|
||||
|
||||
(deftest interrupt-handler-test
|
||||
(deftest shutdown-hook-test
|
||||
(let [script "(-> (Runtime/getRuntime) (.addShutdownHook (Thread. #(println \"bye\"))))"
|
||||
pb (ProcessBuilder. (if tu/jvm?
|
||||
["lein" "bb" "-e" script]
|
||||
|
|
|
|||
Loading…
Reference in a new issue