This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-05-20
Channels
- # announcements (16)
- # babashka (104)
- # beginners (77)
- # bristol-clojurians (1)
- # calva (3)
- # chlorine-clover (50)
- # cider (19)
- # clojure (73)
- # clojure-australia (1)
- # clojure-europe (37)
- # clojure-france (3)
- # clojure-nl (3)
- # clojure-norway (13)
- # clojure-spec (21)
- # clojure-uk (79)
- # clojurescript (225)
- # conjure (102)
- # cursive (11)
- # datascript (1)
- # datomic (1)
- # defnpodcast (1)
- # events (3)
- # figwheel-main (2)
- # fulcro (49)
- # ghostwheel (10)
- # helix (1)
- # kaocha (17)
- # leiningen (10)
- # meander (1)
- # off-topic (26)
- # other-lisps (3)
- # pathom (5)
- # re-frame (40)
- # reagent (6)
- # reitit (33)
- # shadow-cljs (107)
- # testing (3)
- # tools-deps (68)
- # xtdb (16)
- # yada (3)
I see these: clojure-agent-send-pool-%d and clojure-agent-send-off-pool-%d. Something is creating a group of 50 threads in the group "pool-1" following the name "pool-1-thread-N".
I can find references to this naming scheme via google. Not sure where it's coming from though. e.g., https://groups.google.com/d/msg/clojure/2YGRfnZ9hvU/doYP6mjPUKgJ
static class DefaultThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = "pool-" +
poolNumber.getAndIncrement() +
"-thread-";
}
Which is why that old mailing list post shows those names, clojure uses to not set custom names
So you'll need to look at the stack traces of the threads in that pool to determine what is running there (the names won't help)
priority:5 - threadId:pool-1-thread-1 - state:WAITING
stackTrace:
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park([email protected]/Native Method)
- parking to wait for <0x000000076bcffe48> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park([email protected]/LockSupport.java:194)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await([email protected]/AbstractQueuedSynchronizer.java:2081)
at java.util.concurrent.LinkedBlockingQueue.take([email protected]/LinkedBlockingQueue.java:433)
at java.util.concurrent.ThreadPoolExecutor.getTask([email protected]/ThreadPoolExecutor.java:1054)
at java.util.concurrent.ThreadPoolExecutor.runWorker([email protected]/ThreadPoolExecutor.java:1114)
at java.util.concurrent.ThreadPoolExecutor$Worker.run([email protected]/ThreadPoolExecutor.java:628)
at java.lang.Thread.run([email protected]/Thread.java:834)
Locked ownable synchronizers:
- None
This is what you mean, right? It's not obvious who owns that lock from that info.I believe that is an idle threadpool thread, doing nothing waiting to pull work from a queue
You may just need to search for 50 to look for someone creating a fixed threadpool of 50 threads
#!/usr/bin/env bash
while read f; do
if [[ $f =~ *.jar ]]; then
zipgrep '\bpool-' "$f"
else
egrep -Ir '\bpool-' "$f"
fi
done < <(clj -Spath | tr ':' '\n')
Seems like a safe bet. Could also be in a Java lib. For some reason I'm thinking apache something.
I mean, there's not that many places. I'm not totally sure how extensive Cursive's search is. Some statically declare the threadpool size and others pass it in as var. It may not have been constructed with this method.
I bet you find a bunch of the Executors constructors delegate to one main one. Put a breakpoint in there and see what hits it.
just fyi, there is actually a default worker pool built into forkjoin these days. I don't think this is it, but in case that's useful knowledge to anyone in the future
if i pass in a list into this function, 1 is being added to the accumulator on every pass. what is happening to this list on every pass? where do those elements go that get reduced down?
(fn [seq]
;; passes seq into reduce func where accum starts at 0
;; each pass adds 1 to accum
(reduce (fn [x y] (+ x 1)) 0 seq))
The elements of the sequence/list get passed as the values of the parameter y
of the function, and the way that function is defined, it ignores the value of y
.
That is, it gets the value of the elements, but does not do anything with them.
Seems to me elements is ignored and you ended up counting length of list.
What is the easiest way to read EDN data with reader literals, if you dont care about the reader literals. E.g reading a string`"{:foo {:store #cookie-store {:key \"123\"}}"` to clojure value {:foo {:store {:key "123"}
you can use {:default (fn [_ data] data)}
option
https://clojure.github.io/clojure/clojure.edn-api.html#clojure.edn/read
(require '[clojure.edn :as edn])
(edn/read-string
{:default (fn [_ data] data)}
"{:foo {:store #cookie-store {:key \"123\"}}}")
or use the tagged-literal
function in core
as the default
that retains the tagged literal if you print it back out
How do I go about to call the java-provided mod operator %
from within clojure? I know standard java interop but haven't figured out how to call the "core" java built-ins. Clojure's mod
is not good enough since I need the exact behaviour of the java one for compatibility.
Maybe the easiest is to create a java class and just expose a wrapper method? I'll go with that for now but is curious for alternatives. Thanks!
Oh, that does indeed make the tests happy 🙂 Sometimes you just don't know what you are trying to accomplish, it seems. Thanks!
So I want to release a library for use for both clj and cljs. The library has slightly different dependencies for running in cljs than in clj. What’s the correct way to handle this? Should I just include both the clj and cljs dependencies in my pom.xml?
…and on a related note, should I be including Clojure/ClojureScript as dependencies in the released jar?
Have you tried before to pass a thread-first as a argument for a function?
(defn- wrap-exception
[f info]
(try
f
(catch Exception e
(log/error "Exception was handled: " (.getClass e) ": " (.getMessage e))
(throw (ex-info info {:status 500
:message (.getMessage e)})))))
I want to pass a thread-first function on it for avoid using try catch all the timesurely that should be (try (f) ...)
how would thread-first help here? how would you pass the macro as an argument?
On the example, i update something in database and then handle the result. i use it for make it more readable.
(-> (persist/update-subcategory datasource body id)
(handle-result id :update))
(wrap-exception
(-> (persist/update-subcategory datasource body id)
(handle-result id :update))
"Subcategory was not updated.")
The big picture of itthat's a reasonable way to use try/catch but it doesn't really matter if what is inside is ->
, or just a nested form, or a let
block
I asked because I didn't see the connection
Ok. Thanks