-
Acknowledge that you might actually want to use Propel instead of relying on this Gist.
-
Clone this Gist:
git clone https://gist.github.com/eerohele/e06551b115c6a31d1280a115c4c2abb2 prepl
-
Open the project in your favorite editor/IDE.
-
Start evaluating the forms in
prepl.clj
one by one.
Last active
November 6, 2021 19:10
-
-
Save eerohele/e06551b115c6a31d1280a115c4c2abb2 to your computer and use it in GitHub Desktop.
A minimal, annotated example of using Clojure prepl with core.async
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{:deps {org.clojure/core.async {:mvn/version "0.5.527"}}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(comment | |
(require '[clojure.core.async :as async]) | |
(require '[clojure.core.server :as server]) | |
(import '(java.io PipedReader PipedWriter)) | |
;; Start a prepl server. | |
;; | |
;; The prepl server is started in a new thread, so this call doesn't block. | |
(def server | |
(server/start-server {:accept 'clojure.core.server/io-prepl | |
;; Passing in 0 causes the prepl server to pick a | |
;; random available port number. | |
:port 0 | |
:name "jvm"})) | |
;; Just in case you need to stop the server. | |
#_(.close server) | |
;; Create a pipe comprising a PipedWriter and a PipedReader. | |
;; | |
;; You can send the output of one program (or thread) to the pipe and have | |
;; another program (or thread) read that output from the pipe. | |
(def writer (PipedWriter.)) | |
(def reader (PipedReader.)) | |
;; Connect the reader to the writer. The pipe won't work unless the two halves | |
;; (reader and writer) are connected. | |
;; | |
;; You can also pass the reader to the writer's constructor or vice versa. The | |
;; order doesn't matter. | |
(.connect reader writer) | |
;; The core.async channel prepl reads from. | |
(def in-chan (async/chan)) | |
;; The core.async channel prepl writes to. | |
(def out-chan (async/chan)) | |
;; Start a prepl client. You have to start it in another thread, because | |
;; the loop that reads from `reader` is infinite. | |
(let [port (.getLocalPort server) | |
;; Write whatever the prepl server returns into the output channel. | |
out-fn #(async/>!! out-chan %)] | |
(async/thread | |
(server/remote-prepl "localhost" port reader out-fn))) | |
;; Start a loop that reads everything from the input channel and writes it to | |
;; the specified pipe (PipedWriter). | |
;; | |
;; Everything this loop writes to the pipe is readable by other programs (or | |
;; threads). | |
(async/go-loop | |
[] | |
(when-let [input (async/<! in-chan)] | |
(.write writer input) | |
(.flush writer) | |
(recur))) | |
;; Put a code string to evaluate on the input channel | |
;; and read the response from the output channel. | |
(async/go | |
(async/>! in-chan "(select-keys {:a 1 :b 2 :c 3} [:a :c])") | |
(prn (async/<! out-chan))) | |
(.close reader) | |
(.close writer) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment