Skip to content

Commit 864cd09

Browse files
committed
Introduced in process nrepl message processing
1 parent 9e2902d commit 864cd09

2 files changed

Lines changed: 70 additions & 20 deletions

File tree

src/gorilla_repl/core.clj

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@
2222
(POST "/save" [] (handle/wrap-api-handler handle/save))
2323
(GET "/gorilla-files" [] (handle/wrap-api-handler handle/gorilla-files))
2424
(GET "/config" [] (handle/wrap-api-handler handle/config))
25-
(GET "/repl" [] ws-relay/ring-handler)
26-
(route/resources "/" {:root "gorilla-repl-client"})
27-
(route/files "/project-files" {:root "."}))
25+
;; (GET "/repl" [] (ws-relay/repl-ring-handler ws-relay/on-receive-mem))
26+
(GET "/repl" [] (ws-relay/repl-ring-handler ws-relay/on-receive-net))
27+
(route/resources "/")
28+
(route/files "/project-files" [:root "."]))
2829

2930

3031
(defn run-gorilla-server

src/gorilla_repl/websocket_relay.clj

Lines changed: 66 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@
66

77
(ns gorilla-repl.websocket-relay
88
(:require [org.httpkit.server :as server]
9+
[clojure.tools.nrepl.server :as nrepl-server]
910
[clojure.tools.nrepl :as nrepl]
11+
[clojure.tools.nrepl [transport :as transport]]
12+
[gorilla-repl.render-values-mw :as render-mw] ;; it's essential this import comes after the previous one!
13+
[cider.nrepl :as cider]
14+
[ring.middleware.session :as session]
15+
[ring.middleware.session.memory :as mem]
1016
[cheshire.core :as json]))
1117

1218
;; We will open a single connection to the nREPL server for the life of the application. It will be stored here.
@@ -20,26 +26,69 @@
2026
(let [new-conn (nrepl/connect :port port)]
2127
(swap! conn (fn [x] new-conn))))
2228

23-
(defn- send-json-over-ws
24-
[channel data]
25-
(let [json-data (json/generate-string data)]
26-
#_(println json-data)
27-
(server/send! channel json-data)))
29+
(def ^:private nrepl-handler (apply nrepl-server/default-handler
30+
(-> (map resolve cider/cider-middleware)
31+
(conj #'render-mw/render-values))))
32+
33+
(defn- process-replies
34+
[reply-fn replies]
35+
(doall (->> replies
36+
(map reply-fn))))
2837

29-
(defn- process-message
38+
(defn- process-message-net
3039
[channel data]
3140
(let [parsed-message (assoc (json/parse-string data true) :as-html 1)
3241
client (nrepl/client @conn Long/MAX_VALUE)
3342
replies (nrepl/message client parsed-message)]
3443
;; send the messages out over the WS connection one-by-one.
35-
(doall (map (partial send-json-over-ws channel) replies))))
36-
37-
(defn ring-handler
38-
"This ring handler expects the client to make a websocket connection to the endpoint. It relays messages back and
39-
forth to an nREPL server. A connection to the nREPL server must have previously been made with 'connect-to-nrepl'.
40-
Messages are mapped back and forth to JSON as they pass through the relay."
41-
[request]
42-
(server/with-channel
43-
request
44-
channel
45-
(server/on-receive channel (partial process-message channel))))
44+
(let [reply-fn (partial process-replies
45+
#(server/send!
46+
channel
47+
{:body (json/generate-string %)}))]
48+
(reply-fn replies))))
49+
50+
(defn- process-message-mem
51+
[transport channel timeout data]
52+
(let [msg (assoc (json/parse-string data true) :as-html 1)
53+
[read write] transport
54+
client (nrepl/client read timeout)]
55+
((partial process-replies #(server/send!
56+
channel
57+
{:body (json/generate-string %)
58+
:session {::tranport transport}}))
59+
(do
60+
(when (:op msg)
61+
(future (nrepl-server/handle* msg nrepl-handler write)))
62+
(client)))))
63+
64+
(defn- memory-session
65+
"Wraps the supplied handler in session middleware that uses a
66+
private memory store."
67+
[handler]
68+
(let [store (mem/memory-store)]
69+
(session/wrap-session handler {:store store :cookie-name "gorilla-session"})))
70+
71+
72+
(defn on-receive-net
73+
"Relays messages back and forth to an nREPL server. A connection to the nREPL server must have
74+
previously been made with 'connect-to-nrepl'."
75+
[_ channel]
76+
(partial process-message-net channel))
77+
78+
(defn on-receive-mem
79+
"Passes messages into nREPL (in memory)"
80+
[request channel]
81+
(let [session (:session request)
82+
transport (or (::transport session)
83+
(transport/piped-transports))]
84+
(partial process-message-mem transport channel 1000)))
85+
86+
(defn repl-ring-handler
87+
"Creates a websocket ring handler for nrepl messages. Messages are mapped back and forth to JSON."
88+
[on-receive-fn]
89+
(-> (fn [request]
90+
(server/with-channel
91+
request
92+
channel
93+
(server/on-receive channel (on-receive-fn request channel))))
94+
(memory-session)))

0 commit comments

Comments
 (0)