core-async

Ben Sless 2021-02-24T06:41:28.002200Z

And inconvenient enough to trip up pipeline-async

bhaim123 2021-02-24T07:55:03.002400Z

@ben.sless what do you mean?

ericdallo 2021-02-24T17:11:20.003700Z

In case someone knows how to help 🙂

cassiel 2021-02-24T17:20:56.004600Z

Possibly not too helpful, but here’s what I wrote when I needed something similar a few weeks ago. Shuts down fine when the input channel closes. (defn throttle "Speed limit messages coming into in-ch, echoing to out-chan after a timeout." [in-ch out-ch] (go-loop [held-value nil] (if held-value (alt! in-ch ([v] (when v (recur v))) (a/timeout 500) (do (>! out-ch held-value) (recur nil))) (when-let [v (<! in-ch)] (recur v)))))

ericdallo 2021-02-24T17:23:12.004800Z

Yeah, I tried something like that, but it's a throttle indeed, I want somethig that accepts multiple inputs but delay to take a action

ericdallo 2021-02-24T17:23:17.005Z

anyway, thanks for the input

2021-02-24T17:26:41.005200Z

you are creating a new debounce channel every time you loop in your go loop, you need to create one debounce channel and use the same one for every iteration of your loop

ericdallo 2021-02-24T17:27:56.005400Z

Oh, it makes sense, let me test

ericdallo 2021-02-24T17:30:42.005600Z

Alright, that fixes the issue 😄 but introduce another

ericdallo 2021-02-24T17:31:05.005800Z

If I call multiple times the put!, it does not print the last one only

ericdallo 2021-02-24T17:31:12.006Z

because the out channel is the same

ericdallo 2021-02-24T17:32:47.006200Z

For example, if I call put! 8 times, it prints 8 times with a delay of 1000ms, I was expecting to print only one time, the last one after the 1000ms

pithyless 2021-02-24T17:34:44.006400Z

@ericdallo what are the expected semantics? 1. react to first value as soon as possible 2. debounce for timeout (drop all but the last value seen during this time) 3. return the last value (if seen) after timeout 4. repeat (1) ^ Or something else?

2021-02-24T17:35:39.006600Z

the function as written will only consume from the input once a second, and everything it consumes from the input goes to the output

ericdallo 2021-02-24T17:35:43.006800Z

I expect to always debounce, even if the first, second or any time

2021-02-24T17:36:40.007Z

my description isn't right

ericdallo 2021-02-24T17:37:20.007200Z

• If I call the N time and wait for the ms, it'll print after the ms. • If I call M times inside the ms window, it will print only the last one • every new input, should reset the ms (I expect that from every debounce logic)

ericdallo 2021-02-24T17:37:26.007400Z

Is that clear/makes sense?

2021-02-24T17:38:01.007600Z

if a new input comes in within 1 second of the previous input it should drop the previous

2021-02-24T17:38:23.007800Z

and a new input will cause it to reset the 1 second timer

☝️ 1
pithyless 2021-02-24T17:40:25.008Z

The way I understand it, debounce does not usually reset ms after every input; debounce usually guarantees the first input is returned as fast as possible and then at most one input is returned after timeout passes (which input is returned is usually specific to the domain)

2021-02-24T17:50:56.008400Z

so with your example code changed so the go-loop is like

(let [c (debounce in 1000)]
  (async/go-loop []
    (println (async/<! c))
    (recur)))
I think it behaves like what you described

2021-02-24T17:52:48.008600Z

if I write a bunch of values all at once, only one is printed, if I write three values with a 500 ms delay between them, only one is printed, if I write three with a 1000 ms delay between them, then all three are printed

ericdallo 2021-02-24T17:53:25.008800Z

Oh, that makes sense! and it's quite simple :man-facepalming: thank you very much @hiredman!

ericdallo 2021-02-24T17:53:34.009Z

I confirmed it works as I expected

cassiel 2021-02-24T18:15:37.009200Z

Unless I completely misunderstand the debounce function, I think I’m doing the same thing: as values come in I recur with the most recent value, discarding earlier values, until a timeout, at which point I flush the last value seen. In fact, the only significant difference seems to be that debounce does a condp to determine the channel, whereas I do an alt! and don’t need that. (Also, the version you posted doesn’t seem protected against input closing; the later one on GitHub looks fine.) So, perhaps I don’t understand what you’re trying to achieve?

ericdallo 2021-02-24T18:19:18.009400Z

Yes, thanks for the help, I fixed it here: https://clojurians.slack.com/archives/C05423W6H/p1614186680003700 Also I explains exactly what I meant, sorry for not being clear