2014-11-13 10 views
5

Questa è la versione corrente del codice che svolge un lavoro molto semplice. Avvia 10 routine di go e ogni routine aggiunge 10 messaggi al canale. L'altra estremità è un loop true while che legge il canale e scade ogni 500 ms.Qual è il modo idiomatico di aspettare un canale asincrono Clojure?

Stavo pensando di fare qualcosa di meglio. Penso che il vero ciclo vero possa essere sostituito da un ripetersi in cui legge il canale e dopo ogni lettura riuscita torna a leggerlo di nuovo. Se si verifica un timeout, termina l'esecuzione.

Ho due domande: - è questo l'approccio giusto? - come implementarlo usando idiomatica Clojure

(defn -main [& args] 
    (let [c (async/chan)] 
    (doseq [i (range 10)] 
     (async/go 
     (doseq [j (range 10)] 
      (Thread/sleep (rand-int 1000)) 
      (async/>! c (str i " :: " j))))) 
    (while true 
    (async/<!! 
     (async/go 
     (let [[result source] (async/alts! [c (async/timeout 500)])] 
      (if (= source c) 
      (println "Got a value!" result) 
      (println "Timeout!")))))))) 
+2

Chiamerei qualsiasi uso di 'Thread/sleep' nel codice core.async ** sempre ** un codice olfattivo - stai riempiendo il tuo pool di thread senza una buona ragione. Non posso pensare ad alcuno scenario in cui '

+0

... e, sì, sarei d'accordo sul fatto che una lettura loop/recurata dal canale sarebbe idiomatica. –

risposta

7

Si tratta di un approccio molto comune, in modo da rispondere alla tua prima domanda direi di sì. Ci sono alcune comodità offerte da core.async che potrebbero rendere un po 'più idomatic (anche se è molto bene il modo in cui lo è):

  • uso go-loop a preferenza di (go (while true ...)) o (go (loop ...))
  • uso alt! di preferenza a (let [[result channel]] (alts! ...))
Problemi correlati