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 -- 这是为了友好地对待其他可能“挂起”在末尾的 exec 函数(程序)而添加的。

这种行为变化的原因可能是因为想要能够链式调用函数——所以执行函数本身不能调用shutdown-agentsSystem/exit,因为这会“打断链式调用”,所以只有命令行界面(CLI)能在所有执行函数“完成”后调用这些函数。

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

by
Sean的分析基本正确。这与链式调用无关,因为链式调用还不是一项功能,只是想在执行-X函数时匹配对关闭的预期。这里有几个情况

* 使用future/agent,没有后台线程,期望完整退出。会等待1分钟关闭后台代理池,所以必须要有shutdown-agents或System/exit。
* 有后台线程(如socket服务器)。期望阻塞不退出。不能使用System/exit(这会杀死服务器)。
* 使用future/agent,并且有后台线程(就是这种情况)。期望阻塞不退出。不能使用System/exit(会杀死服务器)或shutdown-agents(会杀死来自服务器的futures/agents)。

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

记录在https://clojure.atlassian.net/browse/TDEPS-198
by
我们在工作中通过将一些功能包装在另一个exec函数中部分解决这个问题,但这样做有点繁琐,并且没有通用性,因此我很高兴看到1.10.3.933中解决了这个问题——谢谢!
...