【问题标题】:Clojure Agent Parellel HTTP IllegalStateException and await-forClojure 代理 Parellel HTTP IllegalStateException 和 await-for
【发布时间】:2013-07-10 05:33:49
【问题描述】:

我正在研究在 Clojure 中发出并行 http 请求的示例,

http://lethain.com/a-couple-of-clojure-agent-examples/

特别是

(ns parallel-fetch
  (:import [java.io InputStream InputStreamReader BufferedReader]
           [java.net URL HttpURLConnection]))

(defn get-url [url]
  (let [conn (.openConnection (URL. url))]
    (.setRequestMethod conn "GET")
    (.connect conn)
    (with-open [stream (BufferedReader.
                       (InputStreamReader. (.getInputStream conn)))]
      (.toString (reduce #(.append %1 %2)
                          (StringBuffer.) (line-seq stream))))))

(defn get-urls [urls]
  (let [agents (doall (map #(agent %) urls))]
    (doseq [agent agents] (send-off agent get-url))
    (apply await-for 5000 agents)
    (doall (map #(deref %) agents))))

(prn (get-urls '("http://lethain.com" "http://willarson.com"))) 

当我在

IllegalStateException await-for in transaction 

这是什么意思,我该如何解决?

【问题讨论】:

  • 奇怪...我刚刚尝试了代码,但没有收到 IllegalStateException 异常。错误消息来自await-for 的定义,但它只应在事务内部使用该函数时显示(即在dosync 内部),因为这就是io! 宏的用途,而我不是在您的代码中查看单个事务。
  • 您能否再次检查您是否在get-urls 中不小心将doseq 输入为dosync,同时移动doseq 表单的最后一个结束括号以包含@987654333 @ 在它的身体里?
  • 是的,仔细检查。当我将代码放入 .clj 文件中然后尝试从 repl 加载它时出现此错误:(use 'parallel-fetch :reload-all) IllegalStateException await-for in transaction clojure.core/await-for (core.clj:2942)
  • 如果注释掉(prn (get-urls '("http://lethain.com" "http://willarson.com"))),通过(use 'parallel-fetch :reload-all)加载代码,然后从REPL执行(prn ,,,)呢?我的猜测是use 正在将代码加载到执行await-for 的事务中。

标签: clojure urlconnection agent illegalstateexception


【解决方案1】:

考虑对问题的评论:

在加载命名空间的过程中正在设置一个事务,并且由于它在顶层调用了get-urls,因此await-for 发生在该事务中并引发异常。

解决此问题的最佳方法是将prn / get-urls 表单放入函数中,并且仅在加载命名空间后调用它。 (如果您想将此代码作为独立应用程序运行,并在 überjar 上使用 lein run 或 java -jar,您可以在 -main 中调用该函数。)

顺便说一句,当您使用:reload-all 时,事务已设置,但并非没有它。 (请参阅私有函数load-lib,它检查:reload-all 的存在并决定使用私有函数load-all(如果存在),以及load-all 本身,这是设置事务的位置。Here's a link to the 1.5.1 source. )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多