(defn my-func [opts]
(assoc opts :something :else))
Run Code Online (Sandbox Code Playgroud)
我想要做的是,将函数的引用(可能通过#'my-func?)序列化为一个字符串,以便我可以在反序列化它时使用args调用它.
这是如何运作的?
在其他问题问如何序列body--全功能代码的功能.我不是问怎么做.我在问如何序列化一个引用.
想象一下,所有运行相同jar的服务器集群都连接到MQ.MQ中的pub fn-reference和fn-argsfor中的函数以及集群中的服务器运行它并确认它.这就是我想要做的事情 - 不要传递函数体.
在某些方面,这就像在clojure中构建一个"无服务器"引擎.
正如评论中所建议的那样,如果您只是序列化该函数的关键字标签并存储/检索该标签,那么您就完成了.
如果你需要将函数从一个地方传送到另一个地方,你基本上需要将函数源代码作为字符串发送,然后eval在另一端编译.这是Datomic在数据库函数存储在数据库中时所执行的操作,并且由Datomic自动运行以对数据库进行任何新的添加/更改(例如,这些可以执行自动数据验证).看到:
对于使用RabbitMQ的分布式计算引擎示例,在Clojure in Action(第1版)一书中使用了类似的技术.
古怪,提交序列化VAR身份刚刚加入到Clojure的昨天:https://github.com/clojure/clojure/commit/a26dfc1390c53ca10dba750b8d5e6b93e846c067
因此,从最新的主快照版本开始,您可以序列化Var(如#'clojure.core/conj)并在另一个JVM上反序列化它,并且可以访问相同的加载代码,并调用它.
(import [java.io File FileOutputStream FileInputStream ObjectOutputStream ObjectInputStream])
(defn write-obj [o f]
(let [oos (ObjectOutputStream. (FileOutputStream. (File. f)))]
(.writeObject oos o)
(.close oos)))
(defn read-obj [f]
(let [ois (ObjectInputStream. (FileInputStream. (File. f)))
o (.readObject ois)]
(.close ois)
o))
;; in one JVM
(write-obj #'clojure.core/conj "var.ser")
;; in another JVM
(read-obj "var.ser")
Run Code Online (Sandbox Code Playgroud)