2013-07-11 5 views
1

내가 Clojure의 병렬 HTTP 요청을 만드는 예제를하고 있어요, 특히Clojure의 에이전트 Parellel HTTP IllegalStateException이하고 기다리고-에 대한

(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"))) 

에서

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

나는이 프로그램을 실행할 때

IllegalStateException await-for in transaction 

이것은 무엇을 의미합니까? 어떻게 수정해야합니까? 트랜잭션이 네임 스페이스를로드하는 과정에서 설정하고 최상위에 get-urls로 전화를 가지고 있기 때문에, await-for 그에서 발생되는

: 계정에 질문에 코멘트를 촬영

+0

이상한 ... 난 단지 코드를 시도하고'IllegalStateException'예외를 얻지 못했습니다. 오류 메시지는 ['await-for'] (http://clojuredocs.org/clojure_core/clojure.core/await-for)에 대한 정의에서 비롯되었지만 트랜잭션 내에서 해당 함수가 사용될 때만 표시되어야합니다 즉,'dosync' 내부에)'io!'매크로가있는 것이고 여러분의 코드에서 하나의 트랜잭션이 보이지 않기 때문입니다. –

+0

실수로 'getq-urls'에'dosync'를 입력하고'doseq' 폼의 마지막 닫는 괄호를'(apply await-for. ..)'그 시체에서? –

+0

그래, 다시 확인했습니다. .clj 파일에 코드를 넣고 repl에서로드하려고하면이 오류가 발생합니다. '(사용 'parallel-fetch : reload-all) clojure.core 트랜잭션에서 IllegalStateException await-for가 발생했습니다./await-for (core.clj : 2942)' –

답변

1

예외를 던집니다.

수정하는 가장 좋은 방법은 prn/get-urls 양식을 함수 안에 넣고 네임 스페이스가로드 된 후에 만 ​​호출하는 것입니다. (당신이 überjar에 lein run 또는 java -jar과 더불어, 독립 실행 형 응용 프로그램으로이 코드를 실행하고자한다면, 당신은 -main 내부에 그 함수에 대한 호출을 넣어 것입니다.) 당신이 :reload-all를 사용할 때

또한, 트랜잭션이 설정되어, 그러나 그것 없이는 아닙니다. (트랜잭션이 설정되는 경우, 이는 자신을 :reload-all의 존재를 확인하고이 있다면 민간 기능 load-all를 사용하기로 결정하는 민간 기능 load-lib를 참조하고, load-all. Here's a link to the 1.5.1 source.)