Fork me on GitHub
#core-async
<
2018-12-18
>
ag03:12:41

can someone help me with this thing: I’m trying to read off a channel and then if :updated-at key of the value is less a second ago, then re-push the entire record back to the channel. Been trying with go-loop, split, other things and still can’t figure this out

ag03:12:53

So idea is to wait until :updated-at is in the past (for at least a second) and then return the value, otherwise keep the channel parked. So if then queried with <!! it would block until :updated-at is 1sec ago

donaldball04:12:19

I feel like I’d want to write a fn that takes an input channel and returns a new output channel:

(defn stalify
  [clock in]
  (let [out (async/chan)]
    (async/go-loop []
      (let [x (async/<! in)]
        (if (some? x)
          (do
            (when-let [pause-ms (compute-pause-if-necessary clock x)]
              (async/<! (async/timeout pause-ms)))
            (when (async/>! out x)
              (recur)))
          (async/close! out))))
    out))

donaldball04:12:44

(Disclaimer: I’ve only written this, not tested it.)

ag05:12:53

hmm… very interesting… thank you. let me play with this

ag05:12:17

@donaldball I don’t think I get this part though:

(when-let [pause-ms (compute-pause-if-necessary clock x)]
              (async/<! (async/timeout pause-ms)))

danboykis05:12:25

@ag that part waits for pause-ms

ag05:12:53

But how exactly. I see it creates a channel that automatically closes after some time, what is it taking out of it though?

danboykis05:12:26

@ag it takes nothing out of it, when a channel closes the result of (async/<! (async/timeout pause-ms)) is nil

danboykis05:12:42

timeout channels automatically close after the passed in duration

ag05:12:39

still don’t get it… sorry… it’s been long day and I’ve been dealing with this thing for a while now

danboykis05:12:59

@ag i wrote a blog post that goes into the details of it, maybe it'll help: http://danboykis.com/posts/core-async-timeout-channels/

ag05:12:58

why when I do something like this it doesn’t work as I expect:

(go-loop []
  (let [x (<! ch)]
    (when (some? x)
      (>! ch x))
    (recur)))

danboykis05:12:23

looks like that'll cause an infinite loop

danboykis05:12:51

if there's anything in ch

ag05:12:24

yes, I wanted to intentionally cause an infinite loop, but it’s not happening and I’m not sure why

markmarkmark13:12:18

@ag the (>! ch x) is parking until something takes the value. that never happens since (presumably) the only thing taking from the channel is this same loop. use put! instead of >! or use a channel with a buffer of at least 1.