Skip to content

Commit

Permalink
nrepl: implement dirac/sticky preferred compiler strategy
Browse files Browse the repository at this point in the history
Sticky strategy attempts to inherit selected compiler settings
on browser refresh. Note that during browser refresh nREPL session
is disconnected and a new nREPL session is created after page load.
That is why we want stickiness for better UX.

This is enabled by default.
  • Loading branch information
darwin committed Oct 9, 2016
1 parent 1c5162f commit cba5995
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 16 deletions.
14 changes: 11 additions & 3 deletions src/nrepl/dirac/nrepl/bootstrap.clj
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
(sessions/add-dirac-session-descriptor! session transport runtime-tag)
(send-bootstrap-info! nrepl-message weasel-url)))

(defn preferred-compiler-selection [sticky? dirac-nrepl-config]
(if sticky?
(state/get-selected-compiler-of-dead-session (:parent-session dirac-nrepl-config)))) ; attempt to stick to previous compiler selection

(defn start-cljs-repl! [nrepl-message dirac-nrepl-config repl-env repl-options]
(log/trace "start-cljs-repl!\n"
"dirac-nrepl-config:\n"
Expand All @@ -49,9 +53,13 @@
initial-session-meta (state/get-session-meta)]
(try
(state/set-session-cljs-ns! 'cljs.user)
(let [preferred-compiler (or (:preferred-compiler dirac-nrepl-config) "dirac/new")]
(if (= preferred-compiler "dirac/new")
(utils/start-new-cljs-compiler-repl-environment! nrepl-message dirac-nrepl-config repl-env repl-options)
(let [preferred-compiler (or (:preferred-compiler dirac-nrepl-config) "dirac/sticky")
want-new? (= preferred-compiler "dirac/new")
want-sticky? (= preferred-compiler "dirac/sticky")]
(if (or want-new? want-sticky?)
(do
(utils/start-new-cljs-compiler-repl-environment! nrepl-message dirac-nrepl-config repl-env repl-options)
(state/set-session-selected-compiler! (preferred-compiler-selection want-sticky? dirac-nrepl-config)))
(state/set-session-selected-compiler! preferred-compiler))) ; TODO: validate that preferred compiler exists
(state/set-session-dirac-nrepl-config! dirac-nrepl-config)
(state/set-session-cljs-repl-env! repl-env)
Expand Down
8 changes: 2 additions & 6 deletions src/nrepl/dirac/nrepl/compilers.clj
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
(let [short-session-id (sessions/humanize-session-id session-id)]
(str "dirac" "/" short-session-id "." number)))

(defn select-compiler! [session id]
(state/set-session-selected-compiler! session id))

; -- compiler management ----------------------------------------------------------------------------------------------------

(defn make-compiler-descriptor [id compiler-env]
Expand Down Expand Up @@ -131,11 +128,10 @@
(state/set-session-last-compiler-number! session next-number)
next-number))

(defn capture-current-compiler-and-select-it! [session]
(defn capture-current-compiler! [session]
(let [session-id (state/get-session-id)]
(log/trace "capture-current-compiler-and-select-it!" session-id)
(assert cljs-env/*compiler*)
(let [compiler-id (make-compiler-id session-id (get-next-compiler-number-for-session! session))
compiler-descriptor (make-compiler-descriptor compiler-id cljs-env/*compiler*)]
(register-compiler-descriptor! session compiler-descriptor)
(select-compiler! session (get-compiler-descriptor-id compiler-descriptor)))))
(register-compiler-descriptor! session compiler-descriptor))))
3 changes: 2 additions & 1 deletion src/nrepl/dirac/nrepl/config.clj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
:weasel-repl {:host "localhost"
:port 8232
:range 10} ; how many ports to try if the default port is taken
:preferred-compiler "dirac/new"
; dirac/sticky means we will inherit preferred compiler from old session on browser refresh
:preferred-compiler "dirac/sticky" ; or "dirac/new", or compiler matching strategy
:cljs-repl-options nil
:repl-init-code standard-repl-init-code
:runtime-tag "unidentified"})
Expand Down
4 changes: 2 additions & 2 deletions src/nrepl/dirac/nrepl/controls.clj
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
(error-println (messages/make-invalid-compiler-error-msg user-input))
(let [session (sessions/get-current-retargeted-session)]
(warn-about-retargeting-if-needed session)
(compilers/select-compiler! session selected-compiler)
(state/set-session-selected-compiler! session selected-compiler)
(let [matched-compiler-descriptor (compilers/find-available-matching-compiler-descriptor session selected-compiler)]
(if (nil? matched-compiler-descriptor)
(error-println (messages/make-no-compilers-msg selected-compiler))))
Expand Down Expand Up @@ -199,7 +199,7 @@
(do
(println (messages/make-report-killed-compilers-msg user-input killed-compiler-ids))
(if-not (compilers/get-selected-compiler-id session) ; switch to first available compiler the current one got killed
(compilers/select-compiler! session nil)) ; note that this still might not guarantee valid compiler selection, the compiler list might be empty
(state/set-session-selected-compiler! session nil)) ; note that this still might not guarantee valid compiler selection, the compiler list might be empty
(state/send-response! (utils/prepare-current-env-info-response))))
(if-not (empty? invalid-compiler-ids)
(error-println (messages/make-report-invalid-compilers-not-killed-msg user-input invalid-compiler-ids))))))))
Expand Down
6 changes: 4 additions & 2 deletions src/nrepl/dirac/nrepl/sessions.clj
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@
(log/error "attempt to add duplicit session descriptor:\n" (debug/pprint-session session))))

(defn remove-dirac-session-descriptor! [session]
(log/debug "remove-dirac-session-descriptor!" (get-session-id session))
(let [session-id (get-session-id session)]
(log/debug "remove-dirac-session-descriptor!" )
(log/trace (debug/pprint-session session))
(state/register-selected-compiler-for-dead-session! session-id (state/get-session-selected-compiler session))
(if-let [session-descriptor (find-dirac-session-descriptor session)]
(swap! state/session-descriptors #(remove #{session-descriptor} %))
(log/error "attempt to remove unknown session descriptor:\n" (debug/pprint-session session))))
(log/error "attempt to remove unknown session descriptor:\n" (debug/pprint-session session)))))

(defn find-matching-dirac-session-descriptors [matcher]
(let [descriptors @state/session-descriptors
Expand Down
13 changes: 12 additions & 1 deletion src/nrepl/dirac/nrepl/state.clj
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
(ns dirac.nrepl.state
(:require [dirac.nrepl.helpers :as helpers]))
(:require [dirac.nrepl.helpers :as helpers]
[clojure.tools.logging :as log]))

; -- global state -----------------------------------------------------------------------------------------------------------

; here we keep a map of all bootstrapped Dirac sessions
(def session-descriptors (atom '()))

; this map will grow indefinitely, it is just a list of strings, not worth recollecting
(def selected-compilers-of-dead-sessions (atom {})) ; session-id -> compiler-id matching strategy (string)

; here we maintain a list of in-progress jobs which want to be echo-ed back to joined-session
(def observed-jobs (atom {}))

Expand Down Expand Up @@ -103,6 +107,7 @@
([selected-compiler] (set-session-selected-compiler! *current-session* selected-compiler))
([session selected-compiler]
(assert session)
(log/debug "setting session selected compiler" (get-session-id session) selected-compiler)
(alter-meta! session assoc ::selected-compiler selected-compiler)))

(defn get-session-compiler-descriptors
Expand Down Expand Up @@ -189,3 +194,9 @@
(assert session)
(reset-meta! session meta)))

(defn register-selected-compiler-for-dead-session! [session-id selected-compiler]
(log/debug (str "register-selected-compiler-for-dead-session! " session-id " => " (pr-str selected-compiler)))
(swap! selected-compilers-of-dead-sessions assoc session-id selected-compiler))

(defn get-selected-compiler-of-dead-session [session-id]
(get @selected-compilers-of-dead-sessions session-id nil))
2 changes: 1 addition & 1 deletion src/nrepl/dirac/nrepl/utils.clj
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
; begin with, because we can't reliably replicate what
; cljs.repl/repl* does in terms of options munging
:init (fn []
(compilers/capture-current-compiler-and-select-it! session))
(compilers/capture-current-compiler! session))
:print (fn [& _]
(log/trace "print-fn (no-op)"))) ; silence any responses
response-fn (partial helpers/send-response! nrepl-message)]
Expand Down

0 comments on commit cba5995

Please sign in to comment.