How can I read pool size
and how many threads
from pool size is currently used?
I want to check if app stop processing because of deadlock, because of too many threads
well actually pool size is easy to determine:
(delay (or (when-let [prop (System/getProperty "clojure.core.async.pool-size")]
(Long/parseLong prop))
8))
there isn't an easy way to see currently used, other than by getting all threads and inspecting their names
thank you, any hints how can I do it?
example of code?
https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html is the main api, unfortunately it dates way back in Java and is pretty creaky
I found this https://gist.github.com/DayoOliyide/f353b15563675120e408b6b9f504628a
yeah, you can go that route too
๐
hmm so I have 22 rows while pool-size is 8โฆ How can I get any conclusions from that? :)
rows?
yes
I don't know what you mean
what is a row?
all of the async pool threads have names like async-dispatch-N
so I think there are 2 there?
oh ok thx, now I have to try it with real issue case
If somebody is interested in:
(defn how-many-async []
(let [thread-set (keys (Thread/getAllStackTraces))
thread-data (mapv bean thread-set)]
(->> (map :name thread-data)
(filter #(.contains % "async-dispatch-"))
(count))))
fast solution but it works, I didnโt try to optimize it, because I need it only for debug nowyou could put that all in one big ->>
(->> (Thread/getAllStackTraces) keys (mapv bean) (map :name) (filter #(.contains % "async-dispatch-")) count)
๐ true, but I was enough satisfy with whatever code which return me right value in this case ๐ Just sharing for others ๐
but still thinking how can I be sure if deadlock is because of pool size. The project is so complex to determine it. I found in all places the number of threads for async is 8
so still canโt be sure, but it is my guess
are you using the new system property that will check for use of blocking async calls in go blocks?
not sure what do you mean?
core.async recently added a system property that will throw if you use a blocking core.async call, >!!, <!!, etc in a go block
-Dclojure.core.async.go-checking=true
that's just one subset of possible blocking calls of course
if you look at the thread dump for those async-dispatch threads, it's usually pretty obvious if it's locked up in this way
I donโt see too many >!! <!! if any in code ,but I see many alt!
and <!
, >!
well those are fine - those are parking ops
if they can't be satisfied, the go block is parked and not consuming a thread
but processing freeze for some reason and I think not always in the same place. At least I have this conclusion from println
if you can just do a thread dump and post it here, I'm happy to look at it
but mostly in the same place
yeah the worst thing is I canโt run it in the REPL easy, because it needs to run cucumber lein cucumber
but I will try to get from this something useful
> if they canโt be satisfied, the go block is parked and not consuming a thread exactly so can be parked forever
yes, but that doesn't match what you're describing
in that case, you'll see 0 threads typically
0? I see 8/8 used in all places, so it can be the issue or not. Not sure why I should see 0?
if everything is parked, then there are no threads doing work
if everything is blocked (on IO or an async blocking operation), then you'll see 8 blocked threads
ie starvation or deadlock
I mean other threads can block 8 threads and wait for >!
in alt!
yours sounds like the latter to me (but of course, both can be true simultaneous too)
no, they can't
hmm
>!
and alt! can only occur in go blocks, which only exist in the dispatch threads
and they don't block
@kwladyka you don't need a repl to get a stack dump - Ctrl-\
in the terminal running the process or jstack
pointed at the jvm PID will also work
or kill -3
on the pid
and to reiterate what @alexmiller already said above, your situation where all 8 threads are blocked can't be caused by >!
or alt!
, you are doing some blocking operation in a go block (io, something extremely CPU intensive, a blocking channel op...)