2024 年 Clojure 调查中分享您的看法!

欢迎!请参阅关于页面,了解更多关于这个网站的信息。

+3
工具
已关闭

与 Clojure CLI 1.10.3.929 中的 -X 和 futures 相关似乎有一个奇怪的问题

$ clojure --version
Clojure CLI version 1.10.3.929
$ clojure -Srepro -X clojure.core.server/start-server :name '"server"' :port 5555 :accept clojure.core.server/repl :server-daemon false
$ clojure -Srepro -J-Dclojure.server.repl="{:port 6666 :accept clojure.core.server/repl}"
$ nc localhost 5555
user=> (def x (future 1))
Execution error (RejectedExecutionException) at java.util.concurrent.ThreadPoolExecutor$AbortPolicy/rejectedExecution (ThreadPoolExecutor.java:2057).
Task java.util.concurrent.FutureTask@14c75e2b[Not completed, task = clojure.core$binding_conveyor_fn$fn__5772@4f4cba65] rejected from java.util.concurrent.ThreadPoolExecutor@5d5b17a8[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 1]
$ nc localhost 6666
user=> (def x (future 2))
#'user/x

我无法在 1.10.3.875 中重现这个问题。

在 1.10.3.882 上,-X 启动根本不起作用,因此我无法进一步缩小范围。

已关闭并注明:“在 Clojure CLI 1.10.3.933 中修复”

1 个答案

+1

已选择
 
最佳答案

我相信在 882 中,-X 调用 System/exit,这就是为什么那个版本不起作用的原因。

905 以相同的方式(终止)行为。

从 912 开始表现出“糟糕”的行为,我相当确信这是因为它们调用 shutdown-agents -- 这是为了对执行函数(程序)友好而添加的(否则会“挂起”在末尾)。

这次行为变化的原因可能是出于想要能够链式调用函数——因此,执行函数本身不能调用 shutdown-agentsSystem/exit,因为这会“打断链式调用”,所以只有命令行接口才能在所有执行函数“完成”后调用这些函数。

在调用 -X 后想要干净的shell退出和想要后台线程保持活跃(如Socket服务器示例)之间存在固有的张力。

Sean的分析基本正确。这实际上并没有与链式调用有关,因为链式调用还未成为功能,只是想要在执行-X函数时满足对关闭的预期。这里有几个情况

* 使用future/agent,没有后台线程,期望完整退出。将等待1分钟以关闭后台代理池,因此必须有shutdown-agents或System/exit。
* 有后台线程(如Socket服务器)。期望阻塞并不退出。不能使用System/exit(或你会杀死服务器)。
* 使用future/agent,并有后台线程(此案例)。期望阻塞并不退出。不能使用System/exit(会杀死服务器)或shutdown-agents(会杀死从服务器运行的未来/代理)。

我认为没有默认情况下适用于所有情况的行为(你总是可以包装一个函数并做你知道是正确的事)。

See also https://clojure.atlassian.net/browse/TDEPS-198
我们在工作中通过用另一个执行函数包装东西来部分解决这个问题,但这样做有点繁琐,而且不具有通用性,所以我很高兴看到在1.10.3.933中解决了这个问题——谢谢!
...