io-prepl not flushing over Unix domain sockets (NIO)? 🧵
I'm building a persistent JVM server that accepts prepl connections over Unix domain sockets (to avoid JVM startup costs). Using Java 21's UnixDomainSocketAddress with NIO channels. Setup:
(let [client (.accept server-channel) ; ServerSocketChannel/UNIX
reader (LineNumberingPushbackReader.
(InputStreamReader. (Channels/newInputStream client)))
writer (OutputStreamWriter. (Channels/newOutputStream client))]
(clojure.core.server/io-prepl :in reader :out writer))
Behavior: Client sends (+ 1 2), server blocks indefinitely. No response sent until client disconnects (triggering EOF). At that point the response finally arrives.
What works fine:
• TCP prepl via -Dclojure.server.foo='{:port 5555 :accept clojure.core.server/io-prepl}' - instant response
• Writing to the same writer directly before io-prepl - flushes fine
Workaround: Reimplemented prepl with explicit (.flush writer) after each prn - works perfectly.
Theory: io-prepl uses flush-on-newline true but something about NIO channel-derived streams doesn't honor this the same way TCP socket streams do?
Has anyone used io-prepl with Unix domain sockets successfully? Am I missing something obvious about how to set up the streams?
Clojure 1.12, Java 21, macOSYou might be getting the exception mentioned here https://docs.oracle.com/javase/8/docs/api/java/nio/channels/Channels.html#newOutputStream-java.nio.channels.WritableByteChannel-
(oh, I guess not)
https://gist.github.com/hiredman/0885c58b55b674770c277f6dab2eac73 is something I've used in the past with the normal repl, I thing mostly the same, maybe with just an extra buffered output stream because of the call to writer
https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/server.clj#L275 I must be blind, doesn't look like it takes :in or :out
We have a ticket related to flushing I think, I know we worked on it for 1.12 but I don't remember if we finished it or not.
Oh, I'm remembering this https://clojure.atlassian.net/browse/CLJ-2645