请在2024年Clojure状态调查!中分享您的想法。

欢迎!请参阅关于页面以获取更多关于如何工作的信息。

0
ClojureScript
如果您在连接到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 功能的测试,但即使禁用,问题仍然存在。

1 答案

0
参考资料: https://clojure.atlassian.net/browse/CLJS-2629(由 mfikes 报告)
...