Context
I have a database connection pool, of size 20. I am writing a function, which makes a bunch of queries to the database, in a recursive manner
Node
- db query: get ids
- for each id:
- db query: get attributes
- recurse if there are subqueries
(I am aware this is an N+1 query, but bear with me that this is required)
Goal
I want to achieve as much parallelism as I can.
Plan
I initially thought I would use a fixed-sized thread pool, which is the same length as the connection-pool-size. (Since the parallelism here is bound by the jdbc connection pool).
Then I could write a function like so:
(defn- query
[{:keys [pool] :as ctx} form]
(let [[where-view eids] (resolve-eids ctx form)
[obj-nodes child-form-nodes]
(cp/pvalues pool
(cp/upmap pool (partial obj-node ctx) eids)
(cp/upmap (partial query-one ctx) (child-forms forms eids)))]
(-> (make-node where-view)
(add-children obj-nodes)
(add-children child-form-nodes))))
Problem
The recursion here could starve the thread-pool, and cause it to hang.
Potential solutions
From research I thought maybe I could use Fork/Join
pools. But I see here Is Java's fork-and-join thread pool is good for executing IO bound task? that these are not quite meant for IO-bound tasks.
What would be the best way for me to achieve this?