core-async

idiomancy 2019-04-02T00:07:35.064200Z

Yeah, I'm probably going to be building something that uses a/map to implement something that has the semantics of mix, because you can't exactly add inputs to a map, although you can create another map that is composed of submaps

2019-04-02T15:13:01.067700Z

I am trying to a/put! all incoming messages from an external API onto a chan. Ususlly consumers have no issues keeping up with producers but occasionally there will be huge bursts of 10k messages from a single producer. I cannot discard any of these messages. What are the usual strategies for dealing with this? Just make my buffer size large enough to account for the largest burst? Implement some sort of logic to group the messages prior to the put!?

2019-04-02T15:15:38.070100Z

the typical amount of messages I'm dealing with is less than 10 per second, and the 10k bursts are rare but predictable, so it doesn't feel quite right to just set the buffer size to 10k, but I could be wrong

bertofer 2019-04-02T15:19:48.071800Z

I would just do that and have a big buffer to account for the bursts, but > Implement some sort of logic to group the messages prior to the put!? depending on how you are implementing the producer. You mentioned is an external API, are you requesting from it? Or your program has the API and each request gets somehow feeded into core.async?

2019-04-02T15:22:42.072200Z

I am requesting from the API, and it answers asynchronously

bertofer 2019-04-02T15:23:28.073200Z

How do you receive the answers?

2019-04-02T15:23:55.073700Z

on a socket. So I just wait for things on the socket and put them on a chan

2019-04-02T15:25:16.075200Z

I should also note that this is an attempt at a library, so I'm hesitant to make the decision for end users regarding buffer size when only certain types of requests require a large buffer for responses. So I guess the best way around this is to allow the users to just pass the whole chan they require themselves with whatever buffer requirements they need

šŸ‘Œ 1
2019-04-02T15:25:37.075700Z

I just wasn't sure if there was some fancy buffer strategy for these type of bursty situations

bertofer 2019-04-02T15:26:56.076800Z

Not that I am aware of, I can think of partitions, debounces, and thinks like that, but are more complex than just a big buffer. Iā€™d go with accepting chan as parameter and let the user choose

2019-04-02T15:27:31.077100Z

ok great, thanks!

idiomancy 2019-04-02T18:09:14.079100Z

wait.... why doesn't this work? when are transducers on channels applied?

idiomancy 2019-04-02T18:09:17.079300Z

(go (>! (chan 1 (map (fnil identity ::NOTHING))) nil))

idiomancy 2019-04-02T18:09:33.079700Z

that returns a "can't put nil on a channel" error

idiomancy 2019-04-02T18:09:50.080100Z

but it seems like it should definitely not do that

alexmiller 2019-04-02T18:11:32.080400Z

nils are not valid channel values

alexmiller 2019-04-02T18:12:14.080600Z

you're putting nil on the channel

alexmiller 2019-04-02T18:13:05.081Z

transducers are applied after you put it on the channel and before you take it off

alexmiller 2019-04-02T18:13:35.081900Z

with some intentional hand-waving about whether it's the producer or consumer thread (as both can occur)

idiomancy 2019-04-02T18:13:38.082Z

after I put it on the channel and before I take it off? So, does that mean its applied as at the beginning of the put take operation?

idiomancy 2019-04-02T18:13:49.082200Z

oh huh

idiomancy 2019-04-02T18:14:25.082400Z

how about in cljs?

idiomancy 2019-04-02T18:14:27.082600Z

no threads

ghadi 2019-04-02T18:14:32.083Z

Same deal.

alexmiller 2019-04-02T18:14:34.083200Z

same semantics

alexmiller 2019-04-02T18:14:41.083700Z

less hand-waving :)

ghadi 2019-04-02T18:14:51.084100Z

A user of a channel knows not that there is a transducer

idiomancy 2019-04-02T18:15:10.084800Z

hahaha, so timing wise, does it occur during the take operation?

ghadi 2019-04-02T18:15:50.086Z

it happens during put

idiomancy 2019-04-02T18:15:58.086300Z

but after the put

idiomancy 2019-04-02T18:16:16.087200Z

so its part of the put operation, and it happens after its already on the channel

ghadi 2019-04-02T18:16:19.087400Z

Sorta yeah. The transducer might be a filter that avoids calling the internal put

idiomancy 2019-04-02T18:16:26.087800Z

it does not

ghadi 2019-04-02T18:16:26.087900Z

So it can't happen during take

idiomancy 2019-04-02T18:16:30.088100Z

as I just verified

idiomancy 2019-04-02T18:16:50.088500Z

I was using it to avoid calling the internal put, but that does not work

ghadi 2019-04-02T18:16:59.088700Z

?

idiomancy 2019-04-02T18:17:47.089200Z

if that was so, this would work (go (>! (chan 1 (map (fnil identity ::NOTHING))) nil))

idiomancy 2019-04-02T18:18:05.089500Z

err

idiomancy 2019-04-02T18:18:06.089700Z

wait

idiomancy 2019-04-02T18:18:08.090Z

hahaha

idiomancy 2019-04-02T18:18:08.090200Z

sorry

idiomancy 2019-04-02T18:18:16.090600Z

i meant this:

idiomancy 2019-04-02T18:18:42.091Z

(go (>! (chan 1 (filter some?)) nil))

ghadi 2019-04-02T18:19:15.091600Z

you can't >! or put! nil, fundamentally

ghadi 2019-04-02T18:19:35.092200Z

no matter what the channel arg is

ghadi 2019-04-02T18:19:41.092500Z

it's an invariant of the system

idiomancy 2019-04-02T18:19:52.092800Z

right, but if the filter occurred before the put operation, then it would never reach that invariant

idiomancy 2019-04-02T18:20:18.093400Z

my expectation is that it simply would never reach out to the transducing process (the put operation)

ghadi 2019-04-02T18:21:16.093900Z

https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/channels.clj#L291 the transducer transforms the internal buffer add operation

idiomancy 2019-04-02T18:22:10.094800Z

ahh, gotcha

idiomancy 2019-04-02T18:23:09.095500Z

hmm. I mean I guess you could just actually use the put operation as the terminal step in a transducer, then...

ghadi 2019-04-02T18:24:03.096100Z

you could do a lot of things šŸ™‚

idiomancy 2019-04-02T18:24:38.096700Z

hahaha, that you could! thanks for the clarification, its really helpful