Tôi đã viết một số mã core.async trong Clojure và khi tôi chạy nó, nó tiêu thụ tất cả bộ nhớ có sẵn và không thành công với lỗi. Có vẻ như sử dụng mapcat
trong đường ống core.async sẽ làm giảm áp lực ngược. (Đó là bất hạnh vì những lý do ngoài phạm vi của câu hỏi này.)Lỗ rò bộ nhớ ở đâu khi mapcat ngắt áp suất trong core.async?
Dưới đây là một số mã đó chứng tỏ vấn đề bằng cách đếm :x
s trong và ngoài của một mapcat
ing dò:
(ns mapcat.core
(:require [clojure.core.async :as async]))
(defn test-backpressure [n length]
(let [message (repeat length :x)
input (async/chan)
transform (async/chan 1 (mapcat seq))
output (async/chan)
sent (atom 0)]
(async/pipe input transform)
(async/pipe transform output)
(async/go
(dotimes [_ n]
(async/>! input message)
(swap! sent inc))
(async/close! input))
(async/go-loop [x 0]
(when (= 0 (mod x (/ (* n length) 10)))
(println "in:" (* @sent length) "out:" x))
(when-let [_ (async/<! output)]
(recur (inc x))))))
=> (test-backpressure 1000 10)
in: 10 out: 0
in: 2680 out: 1000
in: 7410 out: 2000
in: 10000 out: 3000 ; Where are the other 7000 characters?
in: 10000 out: 4000
in: 10000 out: 5000
in: 10000 out: 6000
in: 10000 out: 7000
in: 10000 out: 8000
in: 10000 out: 9000
in: 10000 out: 10000
Các chủng tộc sản xuất xa trước người tiêu dùng.
Dường như tôi không phải là người đầu tiên khám phá điều này. Nhưng lời giải thích cho here dường như không bao gồm nó. (Mặc dù nó cung cấp một cách giải quyết thỏa đáng.) Về mặt khái niệm, tôi cho rằng nhà sản xuất sẽ đi trước, nhưng chỉ bởi độ dài của một vài thông điệp có thể được đệm trong các kênh.
Câu hỏi của tôi là, tất cả các thư khác ở đâu? Bởi dòng đầu ra thứ tư 7000 :x
s không được tính.
Trong liên kết mà bạn đưa ra, Alex đã đề cập đến đây là tình huống khó xử giữa kết quả sai và vi phạm giới hạn bộ đệm. Rõ ràng [ASYNC-124] (http://dev.clojure.org/jira/browse/ASYNC-124) thích câu trả lời đúng – Davyzhu
Vì vậy, về câu hỏi của bạn, các tin nhắn khác có thể được giữ trong 'takers' được tham chiếu [tại đây ] (https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/channels.clj#L86). Không chắc chắn về nó vì vậy chúng ta hãy chờ đợi một câu trả lời tự tin hơn. – Davyzhu