clojurecore.async

Any difference between `(chan n)` and `(chan (buffer n))`?


As the title asks, is there any difference between (chan n) and (chan (buffer n)) when in use?

The question originates from the idea that I want to pull messages from a db (yeah, I do not want to use Kafka or RabbitMQ) and process them in order.

So the code segment looks like:

(defn processer [id]
  (let [ch (chan (buffer 1000))]  ;;(chan 1000) or (chan (buffer 1000))?
    (go-loop []
      (when-let [msg (<! ch)]
        (process-msg msg))
      (recur))
    ch))

(defn enqueue [id]
  (let [ch (processer id)]
    (go-loop []
      (let [msgs (take-100-msg-from-db id)]
        (if (seq msgs)
          (doseq [msg msgs]
            (>! ch msg))
          (<! (timeout 100))))
      (recur))))

In my testing, their behaviours do not differ.


Solution

  • Yes, they are the same.

    You can always look at the source:

    (defn chan
      ([] (chan nil))
      ([buf-or-n] (chan buf-or-n nil))
      ([buf-or-n xform] (chan buf-or-n xform nil))
      ([buf-or-n xform ex-handler]
         (channels/chan (if (number? buf-or-n) (buffer buf-or-n) buf-or-n) xform ex-handler)))