2016-03-21 15 views
0

Ich verwende jet für asynchrone Ringadapter. Jet kommt auch mit async HTTP-Client, der einen Kanal zurückgibt, dessen Wert :body auch ein Kanal ist.Strukturieren clojure Code mit go Blöcke

Auch Async-Server-Route-Handler kann eine Karte zurückgeben, deren :body-Schlüssel einen Kanal enthalten kann. Wenn dieser Kanal geschlossen würde, würde die Antwort an den Client zurückgegeben werden.

ich folgendes schreibe go Code:

(defn- api-call-1 [] 
    (go (-> (jet-client/get "api-url-1") 
      <! 
      :body    ;; jet http client :body is also a channel. 
      <! 
      api-call-1-response-parse))) 


(defn- api-call-2 [] 
    (go (-> (jet-client/get "api-url-2") 
      <! 
      :body 
      <! 
      api-call-2-response-parse))) 


(defn route-function [] 
    (let [response-chan (chan)] 
     (go 
     (let [api-call-1-chan (api-call-1) ;; using channel returned by go 
       api-call-2-chan (api-call-2)] 
       (-> {:api-1 (<! api-call-1-chan) 
        :api-2 (<! api-call-2-chan)} 
        encode-response 
        (>! response-chan))) 
     (close! response-chan)) 
    ;; for not blocking server thread, return channel in body 
    {:body response-chan :status 200})) 

In meinem route-function, ich kann nicht blocken.

Obwohl dieser Code gut funktioniert, ist die Verwendung von go in api-call-1 schlecht?

Ich fand, dass <! in api-call-1 zu verwenden, ich muss es in einen go Block setzen. Jetzt verwende ich diesen go Block-Kanal in route-function. Sieht das uneinheitlich aus? Ich bin besorgt darüber, api-call-1-response-parse oder sogar :body als Kanal zu route-function nicht auszusetzen.

Was ist der richtige Weg, um go Blockcode und Funktionen zu strukturieren? Sollte ich mich um zusätzliche go Blöcke in Funktionen api-call-1/2 kümmern?

Antwort

0

Was Sie haben, sieht ähnlich wie die entsprechende Code ich in der Produktion habe. Das ist ziemlich idiomatisch, daher denke ich, dass Ihr Code richtig strukturiert ist. Die Tatsache, dass core.async-Parkoperationen Funktionsgrenzen nicht überschreiten können, rührt von der Tatsache her, dass es als Makro geschrieben ist und den gesamten Codeabschnitt gleichzeitig verarbeiten muss (oder zumindest solange es lexikalisch verfügbar ist). Dadurch wird der gesamte core.async-Code in dem von Ihnen verwendeten Muster ausgegeben.