如果您在连接到Safari时快速将表单输入到浏览器REPL中,它最终会失败(通常在20个表单以内,但在某些情况下可能会达到100个),Safari会指示
Failed to load resource: The network connection was lost.
在此阶段,对评估表单的响应将不会被发送回终端REPL,终端REPL将阻塞,等待一个永远不会实现的承诺
"main" #1 prio=5 os_prio=31 tid=0x00007fa680011800 nid=0x2603 waiting on condition [0x000070000ad7c000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(
[email protected]/Native Method)
- parking to wait for <0x000000070ad0c030> (a java.util.concurrent.CountDownLatch$Sync)
at java.util.concurrent.locks.LockSupport.park(
[email protected]/LockSupport.java:194)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(
[email protected]/AbstractQueuedSynchronizer.java:871)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(
[email protected]/AbstractQueuedSynchronizer.java:1024)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(
[email protected]/AbstractQueuedSynchronizer.java:1331)
at java.util.concurrent.CountDownLatch.await(
[email protected]/CountDownLatch.java:232)
at clojure.core$promise$reify__8144.deref(core.clj:7029)
at clojure.core$deref.invokeStatic(core.clj:2312)
at clojure.core$deref.invoke(core.clj:2298)
at cljs.repl.browser$browser_eval.invokeStatic(browser.clj:261)
at cljs.repl.browser$browser_eval.invoke(browser.clj:250)
at cljs.repl.browser.BrowserEnv._evaluate(browser.clj:330)
at cljs.repl$evaluate_form.invokeStatic(repl.cljc:546)
at cljs.repl$evaluate_form.invoke(repl.cljc:480)
at cljs.repl$eval_cljs.invokeStatic(repl.cljc:665)
at cljs.repl$eval_cljs.invoke(repl.cljc:658)
at cljs.repl$repl_STAR_$read_eval_print__6488.invoke(repl.cljc:950)
at cljs.repl$repl_STAR_$fn__6494$fn__6503.invoke(repl.cljc:994)
at cljs.repl$repl_STAR_$fn__6494.invoke(repl.cljc:993)
at cljs.compiler$with_core_cljs.invokeStatic(compiler.cljc:1285)
at cljs.compiler$with_core_cljs.invoke(compiler.cljc:1274)
at cljs.repl$repl_STAR_.invokeStatic(repl.cljc:953)
at cljs.repl$repl_STAR_.invoke(repl.cljc:832)
at cljs.cli$repl_opt.invokeStatic(cli.clj:258)
at cljs.cli$repl_opt.invoke(cli.clj:247)
at cljs.cli$main.invokeStatic(cli.clj:577)
at cljs.cli$main.doInvoke(cli.clj:564)
at clojure.lang.RestFn.invoke(RestFn.java:410)
at clojure.lang.AFn.applyToHelper(AFn.java:154)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure.core$apply.invokeStatic(core.clj:659)
at clojure.core$apply.invoke(core.clj:652)
at cljs.main$_main.invokeStatic(main.clj:61)
at cljs.main$_main.doInvoke(main.clj:52)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.lang.AFn.applyToHelper(AFn.java:152)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
在 clojure.lang.Var.applyTo(Var.java:702)
在 clojure.core$apply.invokeStatic(core.clj:657)
在 clojure.main$main_opt.invokeStatic(main.clj:317)
在 clojure.main$main_opt.invoke(main.clj:313)
在 clojure.main$main.invokeStatic(main.clj:424)
在 clojure.main$main.doInvoke(main.clj:387)
在 clojure.lang.RestFn.applyTo(RestFn.java:137)
在 clojure.lang.Var.applyTo(Var.java:702)
在 clojure.main.main(main.java:37)
在 Safari 技术预览版中也能重现此问题,但在 Chrome 或 Firefox 中不能。
重现该问题的方法之一是创建一个包含每行一个形式的文件(比如,一个整数列表),然后将该文件 {{cat}} 到 REPL 中。
cat forms.txt | clj -m cljs.main -ro '{:launch-browser false}' -r
然后使用 Safari 连接到 https://127.0.0.1:9000。
另一种重现错误的方法是使用一个程序来驱动 REPL。下面是一个可以在 Clojure REPL 中执行的程序:
(require '[clojure.java.io :as io])
(let [cmd ["clj" "-m" "cljs.main" "-ro" "{:launch-browser false}" "-r"]
proc (.exec (Runtime/getRuntime) (into-array cmd))
out (.getInputStream proc)
err (.getErrorStream proc)
in (.getOutputStream proc)]
(future (io/copy out *out*))
(future (io/copy err *err*))
(loop [n 0]
(io/copy (io/input-stream (.getBytes (str "(inc " n ")\n"))) in)
(io/copy (io/input-stream (.getBytes (str "(.log js/console " n ")\n"))) in)
(.flush in)
(Thread/sleep (+ 100 (rand-int 200)))
(recur (inc n))))
然后使用 Safari 连接到 https://127.0.0.1:9000。
上述程序包含 JavaScript 控制台日志记录,因此您可以在浏览器控制台中看到计数直到失败。
有趣的是,如果在这里取消 {{Content-Length}} 头部的注释,则问题消失。
https://github.com/clojure/clojurescript/blob/7aca40c4b6131b8e08153809a410c06bdfa567ab/src/main/clojure/cljs/repl/server.clj#L166
这受到 Safari 如何处理此头部的描述以及它如何产生所看到的错误的启发
https://apple.stackexchange.com/a/107868
请注意,这与新的 gzip 代码无关;我尝试了一个禁用了 gzip 功能的测试,但即使禁用,问题仍然存在。