2024年Clojure调查!分享您的想法。

欢迎!请查看关于页面,获取有关此内容的更多信息。

0
REPL

TLDR:我怎样才能启动一个“一次性使用”的远程预处理器连接,该连接运行单个命令,获取返回值,然后释放所有使用的资源?

我曾在 Slack 上提出这个问题,但没有收到回复。在实践中,这通常不是什么大问题,但它困扰了我,所以我决定在这里以更正式的方式记录下来。

我曾认为这是短生命周期的远程预处理器客户端的一个预期用途。它可以使人连接到远程服务器,评估某些内容,获取返回值,然后断开连接。

以下是一些我找到的例子
https://github.com/Olical/how-to-be-a-repl-sorcerer/blob/b6bd530f3d0c6b165248d980d7ce6cd28e8da51f/src/sorcery/main.clj#L20

略有修改

(ns prepl-question
  (:require [clojure.core.server :as server])
  (:import [java.io PipedReader PipedWriter]))

(def srv
  (server/start-server {:accept 'clojure.core.server/io-prepl
                        :port   0
                        :name   "srv"}))

(defn remote-eval [code]
  (with-open [reader (PipedReader.)
              writer (PipedWriter.)]
    (.connect reader writer)
    (let [result! (promise)]
      (future
        (server/remote-prepl
          "localhost" (.getLocalPort srv)
          reader
          (fn [msg]
            (deliver result! msg)))
        (println "DONE"))
      (.write writer code)
      (.flush writer)
      @result!

      ;; doesn't print "DONE"
      (let [r @result!]
        (.close reader)
        (.close writer)

        ;;(.write writer ":repl/quit\n") ;; also tried this
        ;;(.flush writer)

        r))))

(remote-eval "(+ 1 2 3)")

我发现无论如何关闭使用的流,都无法得到“完成”的打印输出,以表示停止预处理器线程循环。

稍微查看了一下远程预处理器的源代码,看起来这里这句话会关闭读取器,但它将在读取器已经关闭时被调用。但至少在上面提到的例子中,我发现在第二次调用 close 时会导致事情永远挂起。我猜这与在此处描述的问题有关:https://stackoverflow.com/a/45703662,与 PipedReader/Writer 设置相关。

但我不确定这能否被认为是在预处理器代码中的一个错误,或者是我使用它的方式不正确。

1 个答案

0
by
我尝试了最新的补丁(伴随着 Printwriter-On 的更改)以及该线程中描述的 "(binding [*out* *err*] (flush))" "黑客解决方案"。不幸的是,这些对我都没有奏效。但这可能与之相关。我很快会花更多时间去研究它,并回来报告。
...