Fork me on GitHub
#core-async
<
2023-01-16
>
robert-stuttaford08:01:09

if i use a buffered chan as a queue - is it somehow possible to detect that the chan has more items in the buffer, when processing a take? use-case is we're using a chan to linearise events in clojurescript in a browser, to ensure that state updates are strictly "single threaded". it'd be great to detect that there are multiple events queued, so that we can process them all before updating state, rather than updating state once per event. i ask because it may be that core.async isn't designed for this, and this isn't possible. hoping to benefit from some more knowledgeable / experienced folks 🙂

phronmophobic08:01:25

It seems like poll! should work for this.

phronmophobic08:01:13

or are you trying to determine if there are more items without actually consuming them from the channel?

robert-stuttaford08:01:18

basically, when processing the next take, i'd like to soak up all buffered items at that time and process them. it may be that what i want isn't actually possible because of the single-threaded nature of js, and what i actually need is timer tick to check for and process whatever's queued, and not use async at all!

robert-stuttaford08:01:24

thanks for the response 🙂

phronmophobic08:01:51

yea, I think something like the following should work

(go
  (loop []
    (let [;; wait for something
          x (<! ch)
          ;; consume until there's nothing left
          batch (loop [batch [x]]
                  (let [x (poll! ch)]
                    (if x
                      (recur (conj batch x))
                      batch)))]
      (process batch))
    (recur)))

phronmophobic08:01:02

you can also add timeouts to allow for more batching

robert-stuttaford08:01:15

nice i'm going to experiment with that, thanks man

robert-stuttaford08:01:07

your example looks like it might work! i wonder though, would successive put! actually be processed before the current take, given the single thread? my guess is no. i'll test to find out, and let you know!

phronmophobic08:01:58

I would also not expect successive puts to arrive in the same batch. for that, I would probably add a short timeout window for grouping multiple values into the same batch

phronmophobic08:01:08

if the producer already naturally groups outputs, then you could also batch at that end.

robert-stuttaford08:01:21

yeah. i thought about that too, but it won't fly; producers are browser events - user clicks and keypresses, xhr callbacks, websocket message callbacks, address changes, etc. we're using core.async to soak and linearise this ad-hoc, unpredictable stream of inputs

👍 2
robert-stuttaford10:01:15

neat, gonna read, thanks Ben!

Ben Sless11:01:05

I think the implementation of batch! should work in cljs

robert-stuttaford11:01:17

cool will check it out