<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Clojure Q&amp;A - Recent questions tagged prepl</title>
<link>https://ask.clojure.org/index.php/tag/prepl</link>
<description></description>
<item>
<title>When using remote prepl server, *repl* is false, preventing use of add-lib and related functions</title>
<link>https://ask.clojure.org/index.php/14374/using-remote-prepl-server-false-preventing-related-functions</link>
<description>&lt;p&gt;To reproduce:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;clojure -J-Dclojure.server.jvm=&quot;{:port 5555 :accept clojure.core.server/io-prepl}&quot;

Clojure 1.12.0
user=&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;then&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nc localhost 5555
*repl*
{:tag :ret, :val &quot;false&quot;, :ns &quot;user&quot;, :ms 0, :form &quot;*repl*&quot;}
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>REPL</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14374/using-remote-prepl-server-false-preventing-related-functions</guid>
<pubDate>Thu, 06 Feb 2025 13:54:48 +0000</pubDate>
</item>
<item>
<title>prepl could have IDs for requests/responses</title>
<link>https://ask.clojure.org/index.php/13934/prepl-could-have-ids-for-requests-responses</link>
<description>&lt;p&gt;Given a pREPL client that evaluates this expr:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(do
    (-&amp;gt; (bound-fn []
          (dotimes [_ 4]
            (Thread/sleep 100)
            (println 1)))
        Thread.
        (doto .start))

    1)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Output will be, correctly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{:tag :ret, :val 1, :ns user, :ms 4, :form (do
        (-&amp;gt; (bound-fn []
              (dotimes [_ 4]
                (Thread/sleep 100)
                (println 1)))
            Thread.
            (doto .start))

        1)}
{:tag :out, :val 1
}
{:tag :out, :val 1
}
{:tag :out, :val 1
}
{:tag :out, :val 1
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, the problem is, that output that came from a thread may be printed anytime, maybe 1 minute from now.&lt;/p&gt;
&lt;p&gt;During that time, many other pREPL requests may have been processed.&lt;/p&gt;
&lt;p&gt;So in absence of an ID, a message like &lt;code&gt;{:tag :out, :val 1}&lt;/code&gt; lacks sufficient context to be able to track where it's coming from.&lt;/p&gt;
&lt;p&gt;Would adding IDs be a good idea?&lt;/p&gt;
</description>
<category>REPL</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13934/prepl-could-have-ids-for-requests-responses</guid>
<pubDate>Sun, 02 Jun 2024 10:33:07 +0000</pubDate>
</item>
<item>
<title>How to create a short-lived remote-prepl such that it can be gracefully shutdown?</title>
<link>https://ask.clojure.org/index.php/13760/create-short-lived-remote-prepl-such-that-gracefully-shutdown</link>
<description>&lt;p&gt;TLDR: How can I start a &quot;one time use&quot; remote-prepl connection that runs a single command, gets the return value, and then releases all resources used?&lt;/p&gt;
&lt;p&gt;I asked this in slack but didn't receive a response. It's probably not usually a big deal in practice but it's been bothering me, so I figured I would more formally log it here.&lt;/p&gt;
&lt;p&gt;I was under the impression that short lived remote-prepl clients is an intended usage. That it should enable one to connect to the remote, eval something, get the return value and disconnect. &lt;/p&gt;
&lt;p&gt;Some example code I found to this effect is here:&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/Olical/how-to-be-a-repl-sorcerer/blob/b6bd530f3d0c6b165248d980d7ce6cd28e8da51f/src/sorcery/main.clj#L20&quot;&gt;https://github.com/Olical/how-to-be-a-repl-sorcerer/blob/b6bd530f3d0c6b165248d980d7ce6cd28e8da51f/src/sorcery/main.clj#L20&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Modified slightly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(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   &quot;srv&quot;}))

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

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

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

        r))))

(remote-eval &quot;(+ 1 2 3)&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I've found no way to get &quot;DONE&quot; to print, signifying the stopping of the prepl thread loop, with any combination of closing the streams used. &lt;/p&gt;
&lt;p&gt;Looking at the remote-prepl source code a bit, it seems like &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/clojure/clojure/blob/f06ef8ad0b3d3ca5cbea64f55e416de1065a65e0/src/clj/clojure/core/server.clj#L341&quot;&gt;this line here&lt;/a&gt; will call close on the reader, but it will be called when the reader is already closed. But at least in the example above, I've found that this causes things to hang forever when &lt;code&gt;close&lt;/code&gt; is called the second time. I'm guessing this is related to the issue described here: &lt;a rel=&quot;nofollow&quot; href=&quot;https://stackoverflow.com/a/45703662&quot;&gt;https://stackoverflow.com/a/45703662&lt;/a&gt;, related to the PipedReader/Writer setup.&lt;/p&gt;
&lt;p&gt;But I'm not sure if this could be considered a bug in the prepl code or if I'm using it wrong. &lt;/p&gt;
</description>
<category>REPL</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13760/create-short-lived-remote-prepl-such-that-gracefully-shutdown</guid>
<pubDate>Tue, 27 Feb 2024 17:04:50 +0000</pubDate>
</item>
<item>
<title>prepl only issues referral warnings once - is that right?</title>
<link>https://ask.clojure.org/index.php/11808/prepl-only-issues-referral-warnings-once-is-that-right</link>
<description>&lt;p&gt;When testing I noticed that my tests for certain warnings when evaluating code in the &lt;code&gt;prepl&lt;/code&gt; pass once and then fail. The warnings are only issued once per session:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ clojure -X clojure.core.server/start-server :name prepl :port 7777 :accept clojure.core.server/io-prepl :server-daemon false &amp;amp;
$ nc localhost 7777
(defn identity [x] x)
{:tag :ret, :val &quot;#'user/identity&quot;, :ns &quot;user&quot;, :ms 1, :form &quot;(defn identity [x] x)&quot;}
(binding [*out* *err*] (flush))
{:tag :err, :val &quot;WARNING: identity already refers to: #'clojure.core/identity in namespace: user, being replaced by: #'user/identity\n&quot;}
{:tag :ret, :val &quot;nil&quot;, :ns &quot;user&quot;, :ms 1, :form &quot;(binding [*out* *err*] (flush))&quot;}
(defn identity [x] x)
{:tag :ret, :val &quot;#'user/identity&quot;, :ns &quot;user&quot;, :ms 1, :form &quot;(defn identity [x] x)&quot;}
(binding [*out* *err*] (flush))
{:tag :ret, :val &quot;nil&quot;, :ns &quot;user&quot;, :ms 1, :form &quot;(binding [*out* *err*] (flush))&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Is this expected behavior?&lt;/p&gt;
</description>
<category>REPL</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11808/prepl-only-issues-referral-warnings-once-is-that-right</guid>
<pubDate>Mon, 25 Apr 2022 22:51:24 +0000</pubDate>
</item>
<item>
<title>clojure.core.server/io-prepl doesn't support read-line</title>
<link>https://ask.clojure.org/index.php/11518/clojure-core-server-io-prepl-doesnt-support-read-line</link>
<description>&lt;p&gt;Repro:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;λ clj -Srepro -M -r
Clojure 1.10.3
user=&amp;gt; (read-line)
Hello, world!
&quot;Hello, world!&quot;
user=&amp;gt; (clojure.core.server/io-prepl)
(read-line)
{:tag :ret, :val &quot;\&quot;\&quot;&quot;, :ns &quot;user&quot;, :ms 2, :form &quot;(read-line)&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice how with io-prepl, (read-line) returns immediately without awaiting for user input and returns an empty string.&lt;/p&gt;
&lt;p&gt;Calling either clojure.main/skip-if-eol or clojure.main/skip-whitespace after read+string in clojure.core.server/prepl appears to fix the issue, but it is admittedly unclear to me why that is.&lt;/p&gt;
</description>
<category>REPL</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11518/clojure-core-server-io-prepl-doesnt-support-read-line</guid>
<pubDate>Thu, 27 Jan 2022 21:42:53 +0000</pubDate>
</item>
<item>
<title>prepl warnings remain buffered until explicit flushing from the client</title>
<link>https://ask.clojure.org/index.php/10735/prepl-warnings-remain-buffered-until-explicit-flushing-client</link>
<description>&lt;p&gt;In a prepl session, Clojure warnings remain buffered and won't be sent to the client without flushing explicitly from the client side.&lt;/p&gt;
&lt;p&gt;Here is an example prepl session using &lt;code&gt;netcat&lt;/code&gt; (the lines starting with &lt;code&gt;;; &lt;/code&gt; indicate responses from the prepl server):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ clojure -X clojure.core.server/start-server :name prepl :port 5555 :accept clojure.core.server/io-prepl :server-daemon false &amp;amp;
$ nc localhost 5555

(set! *warn-on-reflection* true)
;; {:tag :ret, :val &quot;true&quot;, :ns &quot;user&quot;, :ms 2, :form &quot;(set! *warn-on-reflection* true)&quot;}

(.toString (identity &quot;foo&quot;))
;; {:tag :ret, :val &quot;\&quot;foo\&quot;&quot;, :ns &quot;user&quot;, :ms 4, :form &quot;(.toString (identity \&quot;foo\&quot;))&quot;}
(binding [*out* *err*] (flush))
;; {:tag :err, :val &quot;Reflection warning, NO_SOURCE_PATH:2:1 - reference to field toString can't be resolved.\n&quot;}
;; {:tag :ret, :val &quot;nil&quot;, :ns &quot;user&quot;, :ms 4, :form &quot;(binding [*out* *err*] (flush))&quot;}

(defn identity [x] x)
;; {:tag :ret, :val &quot;#'user/identity&quot;, :ns &quot;user&quot;, :ms 3, :form &quot;(defn identity [x] x)&quot;}
(binding [*out* *err*] (flush))
;; {:tag :err, :val &quot;WARNING: identity already refers to: #'clojure.core/identity in namespace: user, being replaced by: #'user/identity\n&quot;}
;; {:tag :ret, :val &quot;nil&quot;, :ns &quot;user&quot;, :ms 2, :form &quot;(binding [*out* *err*] (flush))&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This seems to be caused by the fact that prepl's &lt;code&gt;*err*&lt;/code&gt; PrintWriter is &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/clojure/clojure/blob/a29f9b911b569b0a4890f320ec8f946329bbe0fd/src/clj/clojure/core/server.clj#L224&quot;&gt;not &lt;code&gt;autoFlush&lt;/code&gt;-enabled&lt;/a&gt; and that most of the Clojure warnings are not flushed explicitly.&lt;/p&gt;
&lt;p&gt;Is this an issue to be addressed? Or is it an intended behavior and it's the client's responsibility to flush the error stream on a timely basis?&lt;/p&gt;
</description>
<category>REPL</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10735/prepl-warnings-remain-buffered-until-explicit-flushing-client</guid>
<pubDate>Fri, 25 Jun 2021 13:56:30 +0000</pubDate>
</item>
</channel>
</rss>