2024 Clojure 状态调查!中分享你的想法。

欢迎!请查看关于页面,了解更多关于这个工作方式的信息。

0
Clojure
编辑

我认为我在 core.async 测试中找到一个 bug,以下 mult 测试似乎是纯粹巧合的

;; ASYNC-127 
(let [ch (to-chan! [1 2 3])
      m (mult ch)
      t-1 (chan)
      t-2 (chan)
      t-3 (chan)]
  (tap m t-1)
  (tap m t-2)
  (tap m t-3)
  (close! t-3)
  (is (= 1 (<!! t-1)))
  (is (= nil (a/poll! t-1))) ;; t-2 hasn't taken yet
  (is (= 1 (<!! t-2)))
  (is (= 2 (<!! t-1))) ;; now available
  (is (= nil (a/poll! t-1)))))

core.async/mult 的文档字符串说明:在没有 taps 的情况下接收到的项会被丢弃。根据这句话,通过 to-chan! 放入的 3 项应该被丢弃,因为当 mult 创建时,它会开始在没有 taps 的 mult 上消费它们。

这有道理吗?我忽略了什么吗?

编辑:我发现这个问题 https://clojure.atlassian.net/browse/ASYNC-246,似乎与之相关,在这种情况下,可能是因为项被正确丢弃后,(<!! t-1) 挂起了。

1 答案

0

选定
 
最佳答案

mult 在内部启动一个 go 块。该启动的 go 块与 let 绑定中发生的 taps 之间没有 happens-before 关系。taps 在 mult 开始分配 vals 之前发生是一个完全正常的顺序。

该测试依赖于可能意外发生的一个排序。

你说得对,我的说法确实不准确:“...项目...应该被删除”,更合适的说法可能是“可能会被删除”。异步操作中,无论是被丢弃还是由触碰接受都是正确的行为。测试两边似乎都不可靠,因为它可能在排序不同的情况下失败,可能在不同的设置中(很可能是在https://clojure.atlassian.net/browse/ASYNC-246发生)。
...