This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-11-11
Channels
- # asami (19)
- # babashka (41)
- # beginners (115)
- # biff (7)
- # calva (78)
- # clj-kondo (29)
- # cljs-dev (9)
- # clojure (39)
- # clojure-europe (17)
- # clojure-gamedev (29)
- # clojure-nl (1)
- # clojure-norway (9)
- # clojure-spec (2)
- # clojure-uk (3)
- # clojurescript (7)
- # core-async (26)
- # cursive (16)
- # datomic (13)
- # emacs (1)
- # events (5)
- # fulcro (2)
- # funcool (4)
- # gratitude (1)
- # helix (1)
- # holy-lambda (1)
- # humbleui (1)
- # introduce-yourself (4)
- # java (1)
- # jobs (2)
- # jobs-discuss (9)
- # lsp (28)
- # matcher-combinators (2)
- # mathematics (1)
- # membrane (1)
- # nbb (12)
- # off-topic (10)
- # pathom (52)
- # polylith (38)
- # portal (32)
- # re-frame (4)
- # reagent (16)
- # reitit (2)
- # remote-jobs (1)
- # reveal (1)
- # rewrite-clj (10)
- # sci (67)
- # shadow-cljs (45)
- # squint (1)
- # tools-build (13)
- # tools-deps (16)
(async/pipeline-blocking 3 output (map ab->sync) (async/to-chan!! abs-to-sync))
What I can use if I don’t care about output
. I want to process N things at a time, but I am not interested in to read what functions return.
Let’s say fn is like:
(defn ab->sync [...]
(do-something-and-return-nil))
(defn sync-db [abs-to-sync]
(let [pool-size (.getMaximumPoolSize (get-in dc-integrant/state [:db/postgresql :pools :historical-data]))
output (async/chan 1)
fns-to-run (mapcat
(fn [{:keys [a b]}]
[#(sync-db-spot-trades-from-csv a b)
#(sync-db-spot-candlesticks-1m-from-csv a b)])
abs-to-sync)
ab->sync (fn [f] (f) :chan-cant-get-nil)]
(async/pipeline-blocking pool-size output (map ab->sync) (async/to-chan!! fns-to-run))
(loop []
(when (async/<!! output)
(recur)))))
This is extended version, but I don’t like it. What can I do to make it simpler / better?
First of all output
is not needed here at all. I only need to control number of functions run at a time.
(fn [f] (f) :chan-cant-get-nil)
is so uglyJust stop trying to force a square peg in a round hole, if it doesn't match pipeline don't use pipeline
controlling number of threads running at the same time will be helpful to avoid all kind of complications
Unless you mean to do (repeatedly 4 ...)
to make a 4 threads worker and then queue all this functions. Still not ideal.
@U0NCTKEV8 > use a fixed pool executor Does clojure.async have it? How code looks for that?
I found only this for async
https://stackoverflow.com/questions/18779296/clojure-core-async-any-way-to-control-number-of-threads-in-that-go-thread but it doesn’t so good, because it affects all async
code in the app
To summary this up as I understand there is no function in clojure async to run max N functions at once. Like thread pool size. Then start N workers reading from 1 chan is the best idea which I have. Alternatively Java interop with thead pool executor
(let [pool-size (.getMaximumPoolSize (get-in dc-integrant/state [:db/postgresql :pools :historical-data]))
fns-to-run (mapcat (fn [{:keys [a b]}]
[#(sync-db-spot-candlesticks-1m-from-csv a b)
#(sync-db-spot-trades-from-csv a b)])
abs-to-sync)
fns-chan (async/to-chan!! fns-to-run)]
(dotimes [_ pool-size]
(async/go-loop []
(when-let [f (async/<! fns-chan)]
(f)
(recur)))))
Finally this.Looks like you will be doing i/o inside that go-loop (fns-to-run seem to be doing io), probably better to use (a/thread (loop [] …))