2016-11-09 59 views
3

我在Clojure去塊中使用線程/睡眠有內部衝突。所以一般不建議有內部的任何長期運行的進程去塊,Stuart Sierra mentions that sleeping in go block is not preferredClojure去塊中的線程/睡眠

一般情況下,它不會阻塞,睡眠,還是我的任何工作/ O可以被安全地放置在一展身手而不會對系統的吞吐量產生重大影響。

在我的情況下,我想收聽某個頻道上的信息,並在通知用戶它們來之前將它們分組。或者,如果只有一條消息出現,請通知用戶。在我的特殊使用案例中,很多消息要麼快速連續發佈,要麼獨自發布,而且消息不可能定期發佈。

爲了實現這一點,我有一個go-loop塊,等待通道上的輸入。當它收到時,它睡一會兒(最多一兩秒鐘),同時檢查是否有任何其他輸入到達頻道,並基於此通知用戶整個事情或只傳遞第一條消息。

我不會在我的應用程序中有一堆這樣的go塊,只有一塊。由於Clojure總是會產生更多的線程來服務塊,因此在睡眠中阻塞一個線程在實踐中應該不成問題。但是從理論上講,我不知道是否有一種更優雅的方式來處理這個問題,而不需要像這樣綁定一個線程?

回答

9

而不是阻止在Thread/sleep你應該使用clojure.core.async/timeout。有an example on ClojureDocs非常類似於你的場景:

(go-loop [seconds (atom 0) 
      add-seconds! #(swap! seconds + %)] 
    (println "Waiting 1 second") 
    (<! (timeout 1000)) 
    (add-seconds! 1) 
    (println "Waiting 2 seconds") 
    (<! (timeout 2000)) 
    (add-seconds! 2) 
    (println 
    (format "Waited %s seconds" 
      @seconds))) 
+0

感謝一堆,超時是完美的我的目的! – Domchi