This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-06-10
Channels
- # aleph (4)
- # announcements (27)
- # aws (12)
- # aws-lambda (1)
- # beginners (207)
- # boot (4)
- # calva (8)
- # cider (9)
- # clj-kondo (9)
- # cljs-dev (27)
- # cljsrn (6)
- # clojure (104)
- # clojure-android (3)
- # clojure-dev (9)
- # clojure-finland (2)
- # clojure-italy (18)
- # clojure-spec (8)
- # clojure-uk (100)
- # clojurescript (43)
- # clojutre (1)
- # core-async (49)
- # cursive (18)
- # data-science (3)
- # duct (24)
- # events (2)
- # fulcro (27)
- # immutant (1)
- # off-topic (32)
- # om (2)
- # onyx (2)
- # pathom (14)
- # pedestal (2)
- # planck (3)
- # re-frame (38)
- # reagent (7)
- # reitit (10)
- # rewrite-clj (7)
- # ring-swagger (3)
- # shadow-cljs (32)
- # spacemacs (63)
- # test-check (16)
- # tools-deps (5)
- # vim (21)
@hiredman It appears the promise-chan issue we discussed last week is somewhat worse than I thought. It looks like a fulfilled promise-chan will always be preferred by alts! to a timeout chan, even if the timeout chan has already been triggered (ie, x millis have passed).
alts! randomizes the order in which it evaluates channels unless you set :priority @pmooser
If you alts! over ready channels (like a fulfilled promise or an elapsed timeout) you should get an even distribution of chosen ops
@ghadi if you have an alts! in a loop, even if the timeout expires, the js thread isn't yielded, so the fact that the timeout has expired is never registered
I actually have not run that snippet in clj, so I'm not sure if it would be the same.
I don't agree. I mean I "understand why" from the implementation, but it doesn't make sense in "this is non-surprising and what everyone would expect from a supposedly non-deterministic choice".
In my opinion, we shouldn't have to know the type of chans to know if our code will behave as expected - especially since chans have no mechanism for tracking identity, like a name or even an IMeta implementation.
Anyway, I am guessing this will never be addressed but it is definitely unfortunate. I just provided my own implementation of promise-chan that doesn't do this (because it is not based on an infinite buffer) and we will probably always avoid the other one just to be sure not to run into this.
I think it's basically an edge case of an implementation detail that rears its head because most buffers won't infinitely provide values (and thus be preferred indefinitely).
I wrote my own, and didn't implement it as a buffer. I implement ReadPort and WritePort myself, with a go-loop handling reads and writes (and deferring to some internal chans).
Basically the trick (I think) is that I'm providing the same API, but because I'm falling back to operations on normal many-to-many chans and using a go-loop to ferry values around, it does yield as expected.
So it looks like any buffered chans with ready values will always be preferred over the timeout chan, even if the timeout has already triggered.
Sure, but the reason a promise chan is "the problem" for me is that no other chan (that I know of) will indefinitely provide values. Ie, a normal buffered chan will exhaust its buffer pretty soon, and then at least timeouts/etc will get a chance.
So while it isn't specific to promise chan technically, the fact that it can basically get "stuck" doesn't really occur with any other buffer implementation I've seen.
cljs.user=> (dotimes [i 10] (println (clojure.core.async/random-array 2)))
WARNING: var: cljs.core.async/random-array is not public at line 1 <cljs repl>
#js [1 0]
#js [1 0]
#js [1 0]
#js [1 0]
#js [1 0]
#js [1 0]
#js [1 0]
#js [1 0]
#js [1 0]
#js [1 0]
@pmooser @hiredman I had a feeling we didn't have all the facts straight. alts!
is broken in the 2 channel but not in the three+ channel case