This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-08-17
Channels
- # announcements (8)
- # atom-editor (8)
- # aws (1)
- # babashka (96)
- # beginners (128)
- # calva (7)
- # cider (12)
- # cljsrn (1)
- # clojure (75)
- # clojure-europe (28)
- # clojure-hamburg (2)
- # clojure-italy (7)
- # clojure-nl (7)
- # clojure-norway (3)
- # clojure-uk (13)
- # clojurescript (26)
- # conjure (2)
- # cursive (18)
- # data-science (7)
- # datalog (21)
- # datomic (9)
- # duct (15)
- # expound (29)
- # figwheel-main (14)
- # fulcro (59)
- # helix (4)
- # jobs (2)
- # kaocha (19)
- # leiningen (15)
- # luminus (4)
- # malli (57)
- # meander (2)
- # off-topic (2)
- # pathom (12)
- # pedestal (8)
- # re-frame (53)
- # reitit (9)
- # remote-jobs (1)
- # shadow-cljs (64)
- # spacemacs (1)
- # specter (2)
- # tools-deps (12)
- # tree-sitter (2)
- # vim (11)
- # xtdb (17)
Hi all, I am wondering if >!
from a "go block" into a channel is starvation free in Clojure.
For example, if I have two producers and one consumer:
(let [c (chan)]
;; producer 1
(go-loop [count 1] (>! c (str "p1: " count)) (recur (inc count))
;; producer 2
(go-loop [count 1] (>! c (str "p2: " count)) (recur (inc count))
;; only consumer
(go-loop [] (println (<! c)) (recur)))
I am wondering if it is possible one of the producer gets starved? Thanks!note that you're using an unbuffered channel (chan)
so it can hold 0 items. The producers will basically both be trying to rendezvous with the consumer to transfer the value
how that plays out with 2 producers is somewhat arbitrary and based on how notification happens at the java layer, there are no guarantees on the puts between the 2 producers
so you might see two puts from the first, then some from the second, etc (but they should be in order for each producer)
I came across with this article and apparently Clojure will place blocked puts and takes in a FIFO queue, even for unbuffered channels :thinking_face: https://medium.com/swlh/asynchronous-clojure-a59fa0f9bda0
I think you're missing some of the details - that will happen with put! and take!, but you're using >! and <! which are parking ops and they will simply park (wait, without blocking a thread) until the op can complete with a corresponding take or put
Brains a little slow this morning. I have a map along these lines {#{1 2 3},"a",#{4,5,6},"b",β¦}
and am thinking about f
such that (f 2)
=> a
, (f 6)
=> b
and so on. Maybe this isn't the right structure? I have something ugly using filter
but I feel like there's a simpler way (that isn't unrolling the sets into the map)
(Yes I realise it would probably have taken less time than framing the question in the first place, but then I wouldn't learn anything :))
:) "Larger than the example" should not affect anything because sets are already basically maps, so by wrapping multiple keys in sets you're not saving anything.
Actually I do have another approach using (vec (concat (repeat x :a) (repeat y :b)))
Ah, but you can just unroll the sets with code, no? No need to unroll them manually, so you can still save on typing.
Yeah, I agree with p-himik here, you can do it with code:
(defn unroll-keys [m]
(into {}
(mapcat (fn [[ks v]] (map #(vector % v) ks)))
m))
Of course, this is UB when the keys aren't disjoint.Thanks, I hadn't thought of unrolling with code. Good idea although I overcame my laziness in the meantime π
Hi
I recall there was some discussion over clojure.cache flaws
for instance, is it possible that cache-get-through
may fail under some intensive load?
endpoint should cache sql queries, but I see about 27M select statements in the db log for last hour (which means cache doesnt work)
do you have any ideas maybe?
thanks
What do you use for state management? An atom maybe?
yes, atom
and no locks?
AFAIK, no locks
in that case when there is a lot of load, meaning multiple thread trying to swap! the cache, one will succeed (eventually), but it will take several tries (queries)
So probably good to wrap it with a locking π
@U1V7K1YTZ The locking might not be necessary if you use delay (swap! C2 cache/through-cache :d (fn [] (delay (do-query))))
interesting!
yes, I think Chris mentioned something like this
Is it preferable to pass around a StringBuilder/cl-format rather than several nested calls to (str)?
it's the "tree falls in a forest" type thing- it makes sense if the scope of the builder is limited to a lexical block where the pattern of usage (append only) is safe, you probably don't want to try to use a StringBuilder that escapes scope
and yes, nested string calls are an antipattern (though apply str
or string/join
will do the stringbuilder stuff for you already)
I'm sure it rarely makes the difference performance wise, unless you're rolling your own serialization lib or something. I have a sick fascination with cl-format. Why should I write all the tedious imperative generation of intermediate representations when I have this (insane, but) perfect DSL to do it for me!
the question is whether the string ops are your bottleneck (and for many domains that can truly be the case - eg. web servers with back end rendering, having a more efficient template tool makes a big difference)
and yes, cl-format is remarkable
cl-format makes me wonder if there's a library out there that implements LOOP using transients that could be used in hot loop situations
haha, LOOP is insane
I'm working on a lib that does low level packed contiguous data structures, that might be a cool feature if I implemented a "hold-my-beer" namespace
the LOOP periodic table from Land of Lisp might be my favourite programming book figure of all time https://blog.idorobots.org/media/lolreview/3.png
Does anyone know who to check for outdated dependencies using Boot?
@contact904 this looks like it wants to do what you need https://github.com/martinklepsch/boot-deps though I can't personally vouch for it
and in all seriousness, if you have the flexibility to do so, I'd consider a boot -> deps.edn switch an improvement / future proofing, not much is happening in the boot ecosystem lately
@contact904 I agree with @noisesmith on switching but if you must stay, that ability is built in to boot's show
https://github.com/boot-clj/boot/blob/master/boot/core/src/boot/task/built_in.clj#L255.
This oddly specific knowledge comes from having used the lib @noisesmith linked a few years ago haha: https://github.com/martinklepsch/boot-deps/pull/12#issuecomment-241523730
Thank you so much!
MacOS just updated, and now clj
gives this error. All the more weird because clojure
seems to work fine.
clojure: error: Cannot execute clojure: No such file or directory
I typically use strace in these situations; may seem like overkill, but itβs typically very obvious which fopen() is causing the error
lrwxr-xr-x 1 dave.dixon admin 36 Aug 17 10:41 /usr/local/bin/clj -> ../Cellar/clojure/1.10.1.561/bin/clj
MacOS screwed something up. Having a similar issue with sbt
, works from the command line, but not from build scripts etc.
I did try a reinstall of the Clojure CLI tools, though without uninstall, same result.
The clojure
command runs fine. It's just clj
that fails.
If I put the full path to clojure
in the rlwrap
command used by clj
, it works. Scratching my head as to what would have changed in MacOS to cause that.
Obviously something like it is no longer picking up the $PATH
value from the shell environment.
@U066LQXPZ Are you aware that Catalina is using zsh is the default shell now instead of bash?
Yes. Though I'm using fish as my shell.
@U016XBH746B I wrote this library a few years back, and used it in production with a few services. https://github.com/jcf/oauth-two The use of Schema is probably no longer desirable and could be removed easily enough.