Fork me on GitHub
#core-async
<
2021-12-18
>
Ben Sless06:12:15

What's the reason reduce is implemented as a function in core.async and not by the reduce interface or protocol?

Benjamin09:12:42

Jo I thought I can call deref on a channel but I can't. didn't Rich mention this in a talk?

Ben Sless09:12:01

What does derefing a channel mean?

Ben Sless09:12:18

But deref shouldn't change the reference. You're just looking at it. Looking is free. Take mutates the channel

Ben Sless09:12:36

If channels had peek then it would be equivalent to deref

Ben Sless09:12:49

But why would you peek in a channel?

Benjamin09:12:31

I see that makes sense. I wanted to use the timeout arg for deref. But I can do it with alts and timeout . Or use future I guess. The use case is doing work with a timeout

Ben Sless09:12:20

I've had a week of "how do I-s" turning into "what are you trying to do" So, what are you trying to do? Are you already building something with core async?

Benjamin09:12:49

I have events and like to handle them async with a timeout. Doesn't matter so much if 1 piece of work fails it's more important that it keeps handling incoming stuff. I'm using a library that puts the events on a channel so there is core.async there. It's something like 1/second

Ben Sless09:12:30

Even when you time something out, you can leak resources because you didn't cancel the process. You take stuff out of a channel, then process it with a timeout?

Ben Sless09:12:22

What sort of processing are you doing?

Ben Sless09:12:42

CPU? Http calls? DB queries?

Benjamin09:12:09

http calls, db queries and more http callls

Benjamin09:12:58

and sometimes waiting for http calls to return

raspasov10:12:29

I believe this was talked about at some point long ago but I don't think it has ever been implemented/released

Ben Sless10:12:18

you need a few things. For each of those, implement a cancellation mechanism, you need it anyway to avoid resource leaks. Then you can implement a uniform interface which times the task out and cancels it

👀 1
raspasov10:12:48

You can also put channels on channels

raspasov10:12:56

I've used that "pattern" when I need to keep processing things, and at the same time each event can have a timeout, retry, etc

Benjamin10:12:31

like putting the channels returned by go into a channel? What can I then do with that?

raspasov10:12:20

It really depends on the use case and the specifics 🙂 I can write a wall of text here but it might only make it more confusing; Just a tool to keep in mind that is available, which might not be obvious, aka the fact that you can put channels on channels

Benjamin10:12:18

yea I try keep it in mind :thumbsup:

Benjamin14:12:34

I'd like to pass a control channel that stops a go-loop when I put :stop, alternatively when I close the channel. What is the usual pattern? If I do <! from the control channel it will park right? So is there always some alt going on?

(a/go-loop []
    (a/alt!
      control :stop
      (a/timeout 300) (do (prn "loop") (recur))))

  (a/>!! control :stop)
doing this now

Ben Sless14:12:32

do you also have an input channel from which you take the loop's inputs?

Ben Sless15:12:41

Then you should utilize the fact that taking from a closed channel returns nil. Instead of a signalling channel close the input

Ben Sless15:12:14

This lends itself to a very nice pattern of automatically cascading shutdown if you build everything with little workers

Benjamin14:12:11

(loop []
    (let [data (a/<!! event-ch)]
      (when-not (= data :disconnect)
        (recur))))
is it fine to have such a loop recuring forever when the channel closes or should it check nil?

Ben Sless15:12:23

Absolutely check for nil

👍 2
raspasov00:12:20

Yeah, if the loop becomes infinite I believe you'll hog a thread from the thread pool (not good)

Al Z. Heymer08:12:55

(loop [] (let [a b] ... (recur))) is not different to (loop [a b] ... (recur b)) . And of course there is go-loop

Ben Sless08:12:29

Not to shill my own library, this is just the pattern I believe should always be used when consuming from a channel: