forked from status-im/status-legacy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathasync.cljs
More file actions
42 lines (39 loc) · 1.71 KB
/
async.cljs
File metadata and controls
42 lines (39 loc) · 1.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
(ns status-im.utils.async
"Utility namespace containing `core.async` helper constructs"
(:require [cljs.core.async :as async]
[status-im.utils.utils :as utils]))
(defn timeout [ms]
(let [c (async/chan)]
(utils/set-timeout (fn [] (async/close! c)) ms)
c))
(defn chunked-pipe!
"Connects input channel to the output channel with time-based chunking.
`flush-time` parameter decides for how long we are waiting to accumulate
value from input channel in a vector before it's put on the output channel.
When `flush-time` interval elapses and there are no values accumulated, nothing
is put on the output channel till the next input arrives, which is then put on
the output channel immediately (wrapped in a vector).
When input channel is closed, output channel is closed as well and go-loop exits."
[input-ch output-ch flush-time]
(async/go-loop [acc []
flush? false]
(if flush?
(do (async/put! output-ch acc)
(recur [] false))
(let [[v ch] (async/alts! [input-ch (timeout flush-time)])]
(if (= ch input-ch)
(if v
(recur (conj acc v) (and (seq acc) flush?))
(async/close! output-ch))
(recur acc (seq acc)))))))
(defn task-queue
"Creates `core.async` channel which will process 0 arg functions put there in serial fashon.
Takes the same argument/s as `core.async/chan`, those arguments will be delegated to the
channel constructor.
Returns task-queue where tasks represented by 0 arg task functions can be put for processing."
[& args]
(let [task-queue (apply async/chan args)]
(async/go-loop [task-fn (async/<! task-queue)]
(task-fn)
(recur (async/<! task-queue)))
task-queue))