Fork me on GitHub
#core-async
<
2020-01-15
>
kwladyka13:01:42

How can I read pool size and how many threads from pool size is currently used?

kwladyka13:01:09

I want to check if app stop processing because of deadlock, because of too many threads

kwladyka14:01:12

well actually pool size is easy to determine:

(delay (or (when-let [prop (System/getProperty "clojure.core.async.pool-size")]
               (Long/parseLong prop))
             8))

Alex Miller (Clojure team)14:01:25

there isn't an easy way to see currently used, other than by getting all threads and inspecting their names

kwladyka14:01:52

thank you, any hints how can I do it?

kwladyka14:01:06

example of code?

Alex Miller (Clojure team)14:01:32

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

Alex Miller (Clojure team)14:01:57

yeah, you can go that route too

kwladyka14:01:14

hmm so I have 22 rows while pool-size is 8… How can I get any conclusions from that? :)

Alex Miller (Clojure team)14:01:41

I don't know what you mean

Alex Miller (Clojure team)14:01:51

all of the async pool threads have names like async-dispatch-N

Alex Miller (Clojure team)14:01:01

so I think there are 2 there?

kwladyka14:01:39

oh ok thx, now I have to try it with real issue case

kwladyka14:01:15

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 now

Alex Miller (Clojure team)14:01:32

you could put that all in one big ->>

Alex Miller (Clojure team)14:01:10

(->> (Thread/getAllStackTraces) keys (mapv bean) (map :name) (filter #(.contains % "async-dispatch-")) count)

kwladyka14:01:37

👍 true, but I was enough satisfy with whatever code which return me right value in this case 🙂 Just sharing for others 🙂

kwladyka14:01:37

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

kwladyka14:01:47

so still can’t be sure, but it is my guess

Alex Miller (Clojure team)14:01:18

are you using the new system property that will check for use of blocking async calls in go blocks?

kwladyka14:01:37

not sure what do you mean?

Alex Miller (Clojure team)14:01:10

core.async recently added a system property that will throw if you use a blocking core.async call, >!!, <!!, etc in a go block

Alex Miller (Clojure team)14:01:30

-Dclojure.core.async.go-checking=true

Alex Miller (Clojure team)14:01:54

that's just one subset of possible blocking calls of course

Alex Miller (Clojure team)14:01:27

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

kwladyka14:01:51

I don’t see too many >!! <!! if any in code ,but I see many alt! and <!, >!

Alex Miller (Clojure team)14:01:06

well those are fine - those are parking ops

Alex Miller (Clojure team)14:01:42

if they can't be satisfied, the go block is parked and not consuming a thread

kwladyka14:01:59

but processing freeze for some reason and I think not always in the same place. At least I have this conclusion from println

Alex Miller (Clojure team)14:01:17

if you can just do a thread dump and post it here, I'm happy to look at it

kwladyka14:01:22

but mostly in the same place

kwladyka14:01:07

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

kwladyka14:01:02

> if they can’t be satisfied, the go block is parked and not consuming a thread exactly so can be parked forever

Alex Miller (Clojure team)14:01:03

yes, but that doesn't match what you're describing

Alex Miller (Clojure team)14:01:22

in that case, you'll see 0 threads typically

kwladyka14:01:23

0? I see 8/8 used in all places, so it can be the issue or not. Not sure why I should see 0?

Alex Miller (Clojure team)15:01:29

if everything is parked, then there are no threads doing work

Alex Miller (Clojure team)15:01:57

if everything is blocked (on IO or an async blocking operation), then you'll see 8 blocked threads

Alex Miller (Clojure team)15:01:24

ie starvation or deadlock

kwladyka15:01:50

I mean other threads can block 8 threads and wait for >! in alt!

Alex Miller (Clojure team)15:01:51

yours sounds like the latter to me (but of course, both can be true simultaneous too)

Alex Miller (Clojure team)15:01:37

>! and alt! can only occur in go blocks, which only exist in the dispatch threads

noisesmith19:01:59

@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

👍 4
noisesmith19:01:39

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...)

👍 4