我想弄清楚如何最好地創建一個異步組件,或以一種組件友好的方式適應異步代碼。這是我能想到的最好的,而且......它感覺不太正確。如何改進此Clojure組件+異步示例?
要義:接話,uppercase
他們和他們reverse
最後print
他們。
問題1:我不能讓system
停止在最後。我期望看到個人c-chan
停止的println
,但不。
問題2:我該如何正確注射貼劑。進入producer
/consumer
fns?我的意思是,它們不是組件,我認爲它們應該是而不是是組件,因爲它們沒有明智的生命週期。
問題3:如何處理慣用命名爲a>b
,並b>c
的async/pipeline
-creating副作用? pipeline
應該是一個組件嗎?
(ns pipelines.core
(:require [clojure.core.async :as async
:refer [go >! <! chan pipeline-blocking close!]]
[com.stuartsierra.component :as component]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PIPELINES
(defn a>b [a> b>]
(pipeline-blocking 4
b>
(map clojure.string/upper-case)
a>))
(defn b>c [b> c>]
(pipeline-blocking 4
c>
(map (comp (partial apply str)
reverse))
b>))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PRODUCER/CONSUMER
(defn producer [a>]
(doseq [word ["apple" "banana" "carrot"]]
(go (>! a> word))))
(defn consumer [c>]
(go (while true
(println "Your Word Is: " (<! c>)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SYSTEM
(defn pipeline-system [config-options]
(let [c-chan (reify component/Lifecycle
(start [this]
(println "starting chan: " this)
(chan 1))
(stop [this]
(println "stopping chan: " this)
(close! this)))]
(-> (component/system-map
:a> c-chan
:b> c-chan
:c> c-chan)
(component/using {}))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; RUN IT!
(def system (atom nil))
(let [_ (reset! system (component/start (pipeline-system {})))
_ (a>b (:a> @system) (:b> @system))
_ (b>c (:b> @system) (:c> @system))
_ (producer (:a> @system))
_ (consumer (:c> @system))
_ (component/stop @system)])
編輯:
我開始思考以下,但我不能肯定它是否正常關閉...
(extend-protocol component/Lifecycle
clojure.core.async.impl.channels.ManyToManyChannel
(start [this]
this)
(stop [this]
(close! this)))
Mount + Async的一個很好的例子,就像你說的那樣,對於較小的用例可能是首選。在爲* this *作品安排Component之前,我實際上花了很多時間在Component *和* Mount上,也就是因爲我喜歡「框架」提供的內容。對我來說,這是一個已經「買進」Component的大型系統,我真的很喜歡爲組件運行一個例子,儘管我會因爲這是一個很好的Mount示例而聽到這個聲音! (加上,我喜歡這是'引導',我打算最終切換:) –
我的意思是更小的情況是什麼都沒用:只是Clojure。 Mount目前在很多大型應用程序中都非常成功地使用。事實上,一週前我剛剛聽到一家公司將他們的20K LOC應用程序從Component轉換爲Mount,並且不能更快樂。我在答案中添加了一個示例組件示例。 – tolitius
我非常感謝你們在提倡和支持'Mount'!與我對斯圖爾特塞拉利昂和weavejester(詹姆斯?)對組件的看法,我懷疑他們對這個玩具問題的處理看起來更通用一些,比如'channel'或'pipeline'組件(帶有'boundary's?),而不是'WordEngine',以及補救你徵收的一些(否則有效的)批評。儘管如此,我們確實有權衡取捨,並且你說服我讓「更多」機會,所以非常感謝!我很感激tolitius! –