Hi Clojure 团队,
在 Liftoff,我们是 Clojure 的大用户(250 多个项目,代码库超过 400k LOC)。我们开发了一些工具,可以根据项目代码的静态分析自动生成 projects 的 deps.edn 文件。
我们的某些工具和测试代码会反复调用 clojure.tools.deps.alpha/resolve-deps。从版本 v0.14.1178 开始,我们注意到以下情况
- resolve-deps 在每次调用时都会创建一个新的 java.util.concurrent.ExecutorService,但在返回前没有关闭它(《代码》(a rel="nofollow" href="https://github.com/clojure/tools.deps.alpha/blob/v0.14.1178/src/main/clojure/clojure/tools/deps/alpha.clj#L477" target="_blank"))。这导致我们的测试代码产生了 20k+ 线程。
- clojure.tools.deps.alpha.util.concurrent/submit-task 将线程绑定推入一个固定大小的线程池,但不会弹出它们(《代码》(a rel="nofollow" href="https://github.com/clojure/tools.deps.alpha/blob/v0.14.1178/src/main/clojure/clojure/tools/deps/alpha/util/concurrent.clj#L34" target="_blank"))。由于线程被重复使用,帧栈持续增长。
我们内部现在正在使用一个修订版的工具,它无条件地在每个 resolve-deps 调用中关闭 ExecutorService,并弹出每个任务的线程绑定。这解决了我们的问题,但我们不知道这是否是一个正确的解决方案。
Clojure 核心团队如何看待 CLI 工具中的并发?我们能否期待 CLI 工具的未来版本发生变化这种行为?
谢谢!