整个出版物被阻止

Whole publication is blocking

我正在按照 this guide 在我的 ClojureScript 应用程序中设置一个 pub/sub 模型,因为我需要多个订阅者来接收放在频道上的所有消息。

在底部,指南说:

It's worth noting that if a publication tries to pass to a channel that's not accepting values, the whole publication will block:

(def loser-chan (chan))
(sub our-pub :loser loser-chan)
(>!! input-chan {:msg-type :loser :text "I won't be accepted"})

Careful: this will return true and won't block, because the publication is taking values from input-chan. But inside the publication, a go block is hanging. The >!! of a :loser value won't block the main thread either, but all following will.

The moral of the story is: if you subscribe a channel to a publication, make sure it can accept values! You should be doing this anyway, but it's especially important when dealing with publications, because you might not have any inkling that something is wrong until some other topic is hanging.

我不明白这一点,但恐怕我 运行 在尝试实现可以​​接受任何事件和 return 的通用函数时遇到了那里描述的问题将接收该事件消息的频道:

(def socket-events (chan))
(def socket-pub (pub socket-events :event-type))

(defn on
  "Given a socket event type, returns a channel
  that subscribes to that event type on the
  socket publication."
  [event-type]
  (let [c (chan)]
    (sub socket-pub event-type c)
    c)))

它按照指南描述的那样工作:工作两次,然后停止工作。

我不明白指南中的非工作示例与工作示例有何不同。据我所知,它看起来与工作输出通道示例完全相同,只是它正在侦听另一个事件。但我认为整个想法是应该能够做到这一点。

我错过了什么?

假设您的意思是 "it works twice",第一个 put 起作用并继续而第二个 put 阻塞,这是由于您订阅的 (chan)。 wiki 中的警告指出,如果有消费者,则整个链块将不再接受。

所以您第一次将 dispatches 放入您的 (chan)(可以容纳一个项目)时发生了什么,但是没有消费者,这会阻塞整个链条。

根据您的用例,您可能希望在 pub/sub 或接收端使用缓冲区。