[#55,#56] add clojure.core.async
This commit is contained in:
parent
93f154283d
commit
5ca10617d3
6 changed files with 143 additions and 9 deletions
34
README.md
34
README.md
|
|
@ -131,6 +131,9 @@ explicitly.
|
||||||
- `sh`
|
- `sh`
|
||||||
- `clojure.java.io` aliased as `io`:
|
- `clojure.java.io` aliased as `io`:
|
||||||
- `as-relative-path`, `copy`, `delete-file`, `file`
|
- `as-relative-path`, `copy`, `delete-file`, `file`
|
||||||
|
- [`clojure.core.async`](https://clojure.github.io/core.async/) aliased as
|
||||||
|
`async`. The `alt` and `go` macros are not available but `alts!!` does work as
|
||||||
|
it is a function.
|
||||||
- [`me.raynes.conch.low-level`](https://github.com/clj-commons/conch#low-level-usage)
|
- [`me.raynes.conch.low-level`](https://github.com/clj-commons/conch#low-level-usage)
|
||||||
aliased as `conch`
|
aliased as `conch`
|
||||||
|
|
||||||
|
|
@ -164,6 +167,20 @@ Waits for TCP connection to be available on host and port. Options map supports
|
||||||
`:timeout` and `:pause`. If `:timeout` is provided and reached, exception will
|
`:timeout` and `:pause`. If `:timeout` is provided and reached, exception will
|
||||||
be thrown. The `:pause` option determines the time waited between retries.
|
be thrown. The `:pause` option determines the time waited between retries.
|
||||||
|
|
||||||
|
- `sig/pipe-signal-received?`. Usage:
|
||||||
|
|
||||||
|
``` clojure
|
||||||
|
(sig/pipe-signal-received?)
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns true if `PIPE` signal was received. Example:
|
||||||
|
|
||||||
|
``` shellsession
|
||||||
|
$ bb '((fn [x] (println x) (when (not (sig/pipe-signal-received?)) (recur (inc x)))) 0)' | head -n2
|
||||||
|
1
|
||||||
|
2
|
||||||
|
```
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
``` shellsession
|
``` shellsession
|
||||||
|
|
@ -308,6 +325,23 @@ $ bb '
|
||||||
(net/wait-for-it "localhost" 1777) (conch/destroy ws)'
|
(net/wait-for-it "localhost" 1777) (conch/destroy ws)'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Async
|
||||||
|
|
||||||
|
Apart from `future` for creating threads and the `conch` namespace for creating
|
||||||
|
processes, you may use `core.async` to script asynchronously. The following
|
||||||
|
example shows how to get first available value from two different processes:
|
||||||
|
|
||||||
|
``` clojure
|
||||||
|
bb '
|
||||||
|
(defn async-command [& args]
|
||||||
|
(async/thread (apply shell/sh "bash" "-c" args)))
|
||||||
|
|
||||||
|
(-> (async/alts!! [(async-command "sleep 2 && echo process 1")
|
||||||
|
(async-command "sleep 1 && echo process 2")])
|
||||||
|
first :out str/trim println)'
|
||||||
|
process 2
|
||||||
|
```
|
||||||
|
|
||||||
## Enabling SSL
|
## Enabling SSL
|
||||||
|
|
||||||
If you want to be able to use SSL to e.g. run `(slurp
|
If you want to be able to use SSL to e.g. run `(slurp
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@
|
||||||
:url "http://opensource.org/licenses/eclipse-1.0.php"}
|
:url "http://opensource.org/licenses/eclipse-1.0.php"}
|
||||||
:source-paths ["src" "sci/src" "sci/inlined" "conch/src"]
|
:source-paths ["src" "sci/src" "sci/inlined" "conch/src"]
|
||||||
:resource-paths ["resources" "sci/resources"]
|
:resource-paths ["resources" "sci/resources"]
|
||||||
:dependencies [[org.clojure/clojure "1.10.1"]]
|
:dependencies [[org.clojure/clojure "1.10.1"]
|
||||||
|
[org.clojure/core.async "0.4.500"]]
|
||||||
:profiles {:test {:dependencies [[clj-commons/conch "0.9.2"]]}
|
:profiles {:test {:dependencies [[clj-commons/conch "0.9.2"]]}
|
||||||
:uberjar {:global-vars {*assert* false}
|
:uberjar {:global-vars {*assert* false}
|
||||||
:jvm-opts ["-Dclojure.compiler.direct-linking=true"
|
:jvm-opts ["-Dclojure.compiler.direct-linking=true"
|
||||||
|
|
|
||||||
68
src/babashka/impl/async.clj
Normal file
68
src/babashka/impl/async.clj
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
(ns babashka.impl.async
|
||||||
|
{:no-doc true}
|
||||||
|
(:require [clojure.core.async :as async]))
|
||||||
|
|
||||||
|
(defn thread
|
||||||
|
[& body]
|
||||||
|
`(~'async/thread-call (fn [] ~@body)))
|
||||||
|
|
||||||
|
(def async-bindings
|
||||||
|
{'async/<!! async/<!!
|
||||||
|
'async/>!! async/>!!
|
||||||
|
'async/admix async/admix
|
||||||
|
'async/alts! async/alts!
|
||||||
|
'async/alts!! async/alts!!
|
||||||
|
'async/buffer async/buffer
|
||||||
|
'async/chan async/chan
|
||||||
|
'async/close! async/close!
|
||||||
|
'async/do-alt async/do-alt
|
||||||
|
'async/do-alts async/do-alts
|
||||||
|
'async/dropping-buffer async/dropping-buffer
|
||||||
|
'async/filter< async/filter<
|
||||||
|
'async/filter> async/filter>
|
||||||
|
'async/into async/into
|
||||||
|
'async/map async/map
|
||||||
|
'async/map< async/map<
|
||||||
|
'async/map> async/map>
|
||||||
|
'async/mapcat< async/mapcat<
|
||||||
|
'async/mapcat> async/mapcat>
|
||||||
|
'async/merge async/merge
|
||||||
|
'async/mix async/mix
|
||||||
|
'async/mult async/mult
|
||||||
|
'async/offer! async/offer!
|
||||||
|
'async/onto-chan async/onto-chan
|
||||||
|
'async/partition async/partition
|
||||||
|
'async/partition-by async/partition-by
|
||||||
|
'async/pipe async/pipe
|
||||||
|
'async/pipeline async/pipeline
|
||||||
|
'async/pipeline-async async/pipeline-async
|
||||||
|
'async/pipeline-blocking async/pipeline-blocking
|
||||||
|
'async/poll! async/poll!
|
||||||
|
'async/promise-chan async/promise-chan
|
||||||
|
'async/pub async/pub
|
||||||
|
'async/put! async/put!
|
||||||
|
'async/reduce async/reduce
|
||||||
|
'async/remove< async/remove<
|
||||||
|
'async/remove> async/remove>
|
||||||
|
'async/sliding-buffer async/sliding-buffer
|
||||||
|
'async/solo-mode async/solo-mode
|
||||||
|
'async/split async/split
|
||||||
|
'async/sub async/sub
|
||||||
|
'async/take async/take
|
||||||
|
'async/take! async/take!
|
||||||
|
'async/tap async/tap
|
||||||
|
'async/thread (with-meta thread {:sci/macro true})
|
||||||
|
'async/thread-call async/thread-call
|
||||||
|
'async/timeout async/timeout
|
||||||
|
'async/to-chan async/to-chan
|
||||||
|
'async/toggle async/toggle
|
||||||
|
'async/transduce async/transduce
|
||||||
|
'async/unblocking-buffer? async/unblocking-buffer?
|
||||||
|
'async/unique async/unique
|
||||||
|
'async/unmix async/unmix
|
||||||
|
'async/unmix-all async/unmix-all
|
||||||
|
'async/unsub async/unsub
|
||||||
|
'async/unsub-all async/unsub-all
|
||||||
|
'async/untap async/untap
|
||||||
|
'async/untap-all async/untap-all})
|
||||||
|
|
||||||
|
|
@ -10,17 +10,35 @@
|
||||||
{;; atoms
|
{;; atoms
|
||||||
'atom atom
|
'atom atom
|
||||||
'swap! swap!
|
'swap! swap!
|
||||||
|
'swap-vals! swap-vals!
|
||||||
'reset! reset!
|
'reset! reset!
|
||||||
'add-watch add-watch
|
'add-watch add-watch
|
||||||
|
'future-call future-call
|
||||||
|
'future (with-meta future {:sci/macro true})
|
||||||
|
'future-cancel future-cancel
|
||||||
|
'future-cancelled? future-cancelled?
|
||||||
|
'future-done? future-done?
|
||||||
|
'future? future?
|
||||||
|
'deref deref
|
||||||
|
'agent agent
|
||||||
|
'send send
|
||||||
|
'send-off send-off
|
||||||
|
'promise promise
|
||||||
|
'deliver deliver
|
||||||
|
'shutdown-agents shutdown-agents
|
||||||
'run! run!
|
'run! run!
|
||||||
'slurp slurp
|
'slurp slurp
|
||||||
'spit spit
|
'spit spit
|
||||||
'pmap pmap
|
'pmap pmap
|
||||||
'print print
|
'pr pr
|
||||||
'pr-str pr-str
|
'pr-str pr-str
|
||||||
'prn prn
|
'prn prn
|
||||||
|
'prn-str prn-str
|
||||||
|
'print-str print-str
|
||||||
|
'print print
|
||||||
'println println
|
'println println
|
||||||
'future-call future-call
|
'println-str println-str
|
||||||
'future (with-meta future {:sci/macro true})
|
'flush flush
|
||||||
'deref deref})
|
'ex-info ex-info
|
||||||
|
'ex-data ex-data
|
||||||
|
})
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
[babashka.impl.File :refer [file-bindings]]
|
[babashka.impl.File :refer [file-bindings]]
|
||||||
[babashka.impl.System :refer [system-bindings]]
|
[babashka.impl.System :refer [system-bindings]]
|
||||||
[babashka.impl.Thread :refer [thread-bindings]]
|
[babashka.impl.Thread :refer [thread-bindings]]
|
||||||
|
[babashka.impl.async :refer [async-bindings]]
|
||||||
[babashka.impl.clojure.core :refer [core-bindings]]
|
[babashka.impl.clojure.core :refer [core-bindings]]
|
||||||
[babashka.impl.clojure.stacktrace :refer [print-stack-trace]]
|
[babashka.impl.clojure.stacktrace :refer [print-stack-trace]]
|
||||||
[babashka.impl.conch :refer [conch-bindings]]
|
[babashka.impl.conch :refer [conch-bindings]]
|
||||||
|
|
@ -147,12 +148,14 @@ Everything after that is bound to *command-line-args*."))
|
||||||
'io/file io/file
|
'io/file io/file
|
||||||
'io/reader io/reader
|
'io/reader io/reader
|
||||||
'edn/read-string edn/read-string
|
'edn/read-string edn/read-string
|
||||||
'net/wait-for-it net/wait-for-it}
|
'net/wait-for-it net/wait-for-it
|
||||||
|
'sig/pipe-signal-received? pipe-signal-received?}
|
||||||
core-bindings
|
core-bindings
|
||||||
system-bindings
|
system-bindings
|
||||||
file-bindings
|
file-bindings
|
||||||
thread-bindings
|
thread-bindings
|
||||||
conch-bindings))
|
conch-bindings
|
||||||
|
async-bindings))
|
||||||
|
|
||||||
(defn read-edn []
|
(defn read-edn []
|
||||||
(edn/read {;;:readers *data-readers*
|
(edn/read {;;:readers *data-readers*
|
||||||
|
|
@ -244,6 +247,7 @@ Everything after that is bound to *command-line-args*."))
|
||||||
t1 (System/currentTimeMillis)]
|
t1 (System/currentTimeMillis)]
|
||||||
(when time? (binding [*out* *err*]
|
(when time? (binding [*out* *err*]
|
||||||
(println "bb took" (str (- t1 t0) "ms."))))
|
(println "bb took" (str (- t1 t0) "ms."))))
|
||||||
|
(flush)
|
||||||
exit-code))
|
exit-code))
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@
|
||||||
(let [tmp (java.io.File/createTempFile "script" ".clj")]
|
(let [tmp (java.io.File/createTempFile "script" ".clj")]
|
||||||
(spit tmp "(defn foo [x y] (+ x y)) (defn bar [x y] (* x y))")
|
(spit tmp "(defn foo [x y] (+ x y)) (defn bar [x y] (* x y))")
|
||||||
(is (= "120\n" (test-utils/bb nil (format "(load-file \"%s\") (bar (foo 10 30) 3)"
|
(is (= "120\n" (test-utils/bb nil (format "(load-file \"%s\") (bar (foo 10 30) 3)"
|
||||||
(.getPath tmp)))))))
|
(.getPath tmp)))))))
|
||||||
|
|
||||||
(deftest preloads-test
|
(deftest preloads-test
|
||||||
;; THIS TEST REQUIRES:
|
;; THIS TEST REQUIRES:
|
||||||
|
|
@ -176,3 +176,12 @@
|
||||||
(net/wait-for-it \"127.0.0.1\" 7171)
|
(net/wait-for-it \"127.0.0.1\" 7171)
|
||||||
(conch/destroy web-server)
|
(conch/destroy web-server)
|
||||||
(net/wait-for-it \"localhost\" 7172 {:timeout 50})"))))
|
(net/wait-for-it \"localhost\" 7172 {:timeout 50})"))))
|
||||||
|
|
||||||
|
(deftest async-test
|
||||||
|
(is (= "process 2\n" (test-utils/bb nil "
|
||||||
|
(defn async-command [& args]
|
||||||
|
(async/thread (apply shell/sh \"bash\" \"-c\" args)))
|
||||||
|
|
||||||
|
(-> (async/alts!! [(async-command \"sleep 2 && echo process 1\")
|
||||||
|
(async-command \"sleep 1 && echo process 2\")])
|
||||||
|
first :out str/trim println)"))))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue