Skip to content

Commit 120a1b8

Browse files
author
dnolen
committed
CLJS-2627: Browser REPL race in send-to-eval
remove the ad-hoc queue, use java.util.concurrent queues
1 parent 7aca40c commit 120a1b8

File tree

2 files changed

+18
-26
lines changed

2 files changed

+18
-26
lines changed

src/main/clojure/cljs/repl/browser.clj

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@
277277
(defn serve [{:keys [host port output-dir] :as opts}]
278278
(binding [ordering (agent {:expecting nil :fns {}})
279279
es (Executors/newFixedThreadPool 16)
280-
server/state (atom {:socket nil :connection nil :promised-conn nil})]
280+
server/state (atom {:socket nil})]
281281
(server/start
282282
(merge opts
283283
{:static-dir (cond-> ["." "out/"] output-dir (conj output-dir))
@@ -383,8 +383,6 @@
383383
:server-state
384384
(atom
385385
{:socket nil
386-
:connection nil
387-
:promised-conn nil
388386
:listeners 0})}
389387
opts))
390388

src/main/clojure/cljs/repl/server.clj

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,38 +13,32 @@
1313
java.io.InputStreamReader
1414
java.io.ByteArrayOutputStream
1515
java.util.zip.GZIPOutputStream
16-
java.net.ServerSocket))
16+
java.net.ServerSocket
17+
[java.util.concurrent ConcurrentLinkedQueue]))
1718

1819
(def ^:dynamic state nil)
20+
(def connq (ConcurrentLinkedQueue.))
21+
(def promiseq (ConcurrentLinkedQueue.))
1922

2023
(defn connection
21-
"Promise to return a connection when one is available. If a
22-
connection is not available, store the promise in server/state."
24+
"Promise to return a connection when one is available. If no connection is
25+
available put the promise into FIFO queue to get the next available
26+
connection."
2327
[]
24-
(let [p (promise)
25-
conn (:connection @state)]
28+
(let [p (promise)
29+
conn (.poll connq)]
2630
(if (and conn (not (.isClosed conn)))
27-
(do
28-
(deliver p conn)
29-
p)
30-
(do
31-
(swap! state (fn [old] (assoc old :promised-conn p)))
32-
p))))
31+
(deliver p conn)
32+
(.offer promiseq p))
33+
p))
3334

3435
(defn set-connection
35-
"Given a new available connection, either use it to deliver the
36-
connection which was promised or store the connection for later
37-
use."
36+
"Given a new available connection, poll the promise queue for and deliver
37+
the connection. Otherwise put the connection into a FIFO queue."
3838
[conn]
39-
(if-let [promised-conn (:promised-conn @state)]
40-
(do
41-
(swap! state
42-
(fn [old]
43-
(-> old
44-
(assoc :connection nil)
45-
(assoc :promised-conn nil))))
46-
(deliver promised-conn conn))
47-
(swap! state (fn [old] (assoc old :connection conn)))))
39+
(if-let [p (.poll promiseq)]
40+
(deliver p conn)
41+
(.offer connq conn)))
4842

4943
(defonce handlers (atom {}))
5044

0 commit comments

Comments
 (0)