评论作者:sfnelson
不好意思,Stuart,我们刚刚注意到您的回复,感谢http://ashtonkemerling.com/blog/2016/06/11/my-increasing-frustration-with-clojure/的公开。
我将尽量解释我们的用例,以便您了解情况,但请理解,这个问题只是一个关于一个看起来和闻起来都像公共API函数(谁知道'eval'会是私有的呢)的函数似乎不一致行为的问题。
我们公司使用Clojure语言构建了一个云平台,该平台根据用户请求在从数据库中加载的模块中进行计算。模块是可信代码,但它们独立于我们的平台,因此可能会有多个相同模块版本同时运行(我们希望避免命名空间冲突)。我们已经研究了多种方法,包括使用在单独JVM中运行的容器和微服务来防止模块之间相互干扰,但为了满足简单查询“这个输入是否有效?”的响应时间要求,我们希望在同一个JVM中运行简单查询。
我们用于响应用户查询的一般方法是构建一个用于计算命名空间(可能需要从计算模块加载其他命名空间),然后在已构建的环境中评估表达式。我们有一个LRU缓存来存储模块命名空间,但我们最终还是会有大量的元空间翻滚,我们通过使用Clojure解释器来处理简单查询(评估太慢)来减轻这种情况。
当我们实现我们的LRU模块命名空间缓存时,我们想要尝试在各自的类加载器中加载模块命名空间,以帮助跟踪类生命周期和GC,并希望允许多个命名空间版本共存。但后来我们得出结论,这是不切实际的,因为Clojure与命名空间相关的全局查找如此之多,因此现在我们预处理模块命名空间,在加载时进行名称摇须,并在缓存到期时显式注销已加载的命名空间,以便其类可以被收集。我们避免在模块中使用像多态方法和协议这样的语言特性,这些特性在模块中使用全局变量。
我们并不是在寻求Clojure团队为我们实现容器(尽管这当然是一个很好的功能),这只是我们在API和实现之间注意到的一个不一致性。Java-Interop eval的预期入口点是什么?