Skip to content

Commit 8b21c5f

Browse files
potetmdnolen
authored and
dnolen
committedFeb 27, 2018
Add handshake for the inner/outer xpc connections of the browser repl
Prior to this commit, the iframe connection just hopes that the roundtrip to the server plus 50ms is enough for the outer xpc connection to get established. This is the reason the browser repl occasionally fails to connect. This commit adds a handshake to that interaction, ensuring that both connections are established prior to sending any work to the outer. Note that it waits for the handshake to complete prior to sending the :ready message to the server. This is slower than sending to both the server and the outer simultaneously, then forcing the inner to wait for an ack from the outer. However, the code is significantly simpler this way. We can revisit if it's an issue.
1 parent 4e2ce83 commit 8b21c5f

File tree

2 files changed

+39
-8
lines changed

2 files changed

+39
-8
lines changed
 

‎.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ closure
1313
*out
1414
.lein*
1515
/pom.xml
16+
*.iml
1617
.repl*
1718
*.swp
1819
*.zip

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

+38-8
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,31 @@
9797
"Start the REPL server connection."
9898
[url]
9999
(if-let [repl-connection (net/xpc-connection)]
100-
(let [connection (net/xhr-connection)]
100+
(let [connection (net/xhr-connection)
101+
repl-connected? (atom false)
102+
try-handshake (fn try-handshake []
103+
(when-not @repl-connected?
104+
(net/transmit repl-connection
105+
:start-handshake
106+
nil)
107+
;; In case we miss, try again. Parent will only
108+
;; ack once.
109+
(js/setTimeout try-handshake
110+
10)))]
111+
(net/connect repl-connection
112+
try-handshake)
113+
114+
(net/register-service repl-connection
115+
:ack-handshake
116+
(fn [_]
117+
(when-not @repl-connected?
118+
(reset! repl-connected? true)
119+
;; Now that we're connected to the parent, we can start talking to
120+
;; the server.
121+
(send-result connection
122+
url
123+
(wrap-message :ready "ready")))))
124+
101125
(event/listen connection
102126
:success
103127
(fn [e]
@@ -115,12 +139,7 @@
115139
(net/register-service repl-connection
116140
:print
117141
(fn [data]
118-
(send-print url (wrap-message :print data))))
119-
120-
(net/connect repl-connection
121-
(constantly nil))
122-
123-
(js/setTimeout #(send-result connection url (wrap-message :ready "ready")) 1000))
142+
(send-print url (wrap-message :print data)))))
124143
(js/alert "No 'xpc' param provided to child iframe.")))
125144

126145
(def load-queue nil)
@@ -189,10 +208,21 @@
189208
connection is made, the REPL will evaluate forms in the context of
190209
the document that called this function."
191210
[repl-server-url]
192-
(let [repl-connection
211+
(let [connected? (atom false)
212+
repl-connection
193213
(net/xpc-connection
194214
{:peer_uri repl-server-url})]
195215
(swap! xpc-connection (constantly repl-connection))
216+
(net/register-service repl-connection
217+
:start-handshake
218+
(fn [_]
219+
;; Child will keep retrying, but we only want
220+
;; to ack once.
221+
(when-not @connected?
222+
(reset! connected? true)
223+
(net/transmit repl-connection
224+
:ack-handshake
225+
nil))))
196226
(net/register-service repl-connection
197227
:evaluate-javascript
198228
(fn [js]

0 commit comments

Comments
 (0)