This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-04-06
Channels
- # beginners (95)
- # boot (3)
- # cider (13)
- # cljs-dev (9)
- # cljsjs (1)
- # cljsrn (35)
- # clojure (78)
- # clojure-dev (5)
- # clojure-italy (6)
- # clojure-nl (9)
- # clojure-russia (13)
- # clojure-spec (1)
- # clojure-uk (74)
- # clojurescript (59)
- # community-development (6)
- # core-async (41)
- # css (110)
- # data-science (2)
- # datomic (22)
- # defnpodcast (1)
- # devcards (1)
- # docs (1)
- # editors (6)
- # emacs (51)
- # figwheel (1)
- # fulcro (66)
- # jobs (1)
- # jobs-discuss (75)
- # lumo (51)
- # mount (2)
- # off-topic (33)
- # pedestal (24)
- # proton (3)
- # re-frame (29)
- # reagent (92)
- # reitit (16)
- # shadow-cljs (16)
- # spacemacs (4)
- # specter (6)
- # vim (6)
- # yada (7)
would a good idiom for consuming exceptions and assertion errors that occur in go blocks be to catch the exception and put it on a dedicated channel for exceptions so it is not lost?
i just spent quite some time tracking down a problem because i never saw the exception and then realized it had happened in the go block
@ajs yes that is a very tricky part of go blocks. have you seen this article? i found it and the stuff it links to helpful. http://martintrojer.github.io/clojure/2014/03/09/working-with-coreasync-exceptions-in-go-blocks
seems like you’ll have to poll both channels or do an alts
type take from both, no?
if you use channels like promises and go blocks as one shot async functions then doing things like having the go block stick any exceptions on its "return" sort of makes sense
what I like to do is treat go blocks as little services processes, and they get a input channel, an output channel, an error channel, and maybe a halt channel
it sort of depends how an why errors might occur, usually an "error" shouldn't bubble out and terminate the go block, it is just an error for a single request it is handling
If my go block is handling fast streaming data, does a try/catch block in Clojure add any overhead for performance ?
right i was bringing my clojurescript bias and forgetting about those nasty ol’ threads 🙂
the clojure (as opposed to clojurescript) version of the go macro has some optimizations where it will emit chunks of the clojure code unaltered if there are no operations in it that need to be exposed in the state machine
so the overhead of a try/catch that doesn't contain any channel operations would be the same in the go macro vs. normal clojure code
if there is a channel operation in there the go macro has to pull it all apart and emulate the jvm's try/catch/finally semantics on the state machine, which I am not sure what the performance difference would be. if I recall the emulated code pushes handler addresses on to a stack and uses the state machine to jump to them, so similar mechanically (I think) to what the jvm must do, but (wild guess) maybe an order of magnitude or two slower because it is in user code
I only use put! when I know for sure the channel has capacity, with put! you are bypassing the built in feedback (upstream producers halt until downstream consumers can handle msgs) that you normally get
I rewrote the how the go macro handles try/catch a few years ago, because it was very broken in a lot of cases, so my emphasis was correctly emulating the semantics of try/catch/finally in normal clojure code
@hiredman Continuing from #clojure... That's all fine, but I don't think you're addressing my concern. I will restate: You're saying the pair [channel value]
, which is passed as element of parameter ports
, is neither a channel nor a port. Later, when one of these elements of ports
is returned, it is apparently never a [channel value]
pair but is always a port or perhaps a channel. Surely that should be mentioned in the docstring?
I am not sure I follow your concern, the docstring reads pretty much like what it is to me
where a single channel / ReadPort represents a take operation, and a pair of [channel value] (where channel implements WritePort) represents a put operation
alts! picks one, and returns [result-of-operation port-or-channel-that-was-operated-on]
both places are called ports but one place is sometimes not a port but a pair that contains a port.