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

欢迎!请查看关于页面获取更多有关操作方式的详细信息。

+2
core.async
  • 每次deref将取通道中的值
  • 从关闭的通道进行deref返回nil
  • 有超时限制的deref必须超时或从通道中取值(不是两者同时)!可能只需要调用通过var的某个alt!!变体。
  • 高效地使用内部实现
  • 不要实现IPending/realized,这两种解释都不太理想。

补丁: async-102-2.patch

deref和定时deref的实现(链接:http://dev.clojure.org/jira/browse/ASYNC-102?focusedCommentId=37211&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-37211 文本:概念上简单),但由于循环命名空间依赖性,实施起来有些困难。欢迎提出建议。

8 个答案

0
评论者:stu_

async-102.patch与描述“当通道关闭时变为realized”不匹配 - 相反,通道只有在当前有可用值时才会变成realized。这这两种解释在我看来都存在问题,我认为需要明确{{realized?}}的定义以支持这种新情况。Clojure中{{realized?}}的所有其他使用都保证了后续的deref将立即填充,但如果有另一个消费者取走该值,通道的情况则不会是这样。

一旦解决这个问题,我需要在筛选之前提供更好的core.async实现协议的文档字符串。关于线程的用法有哪些保证?工作在哪里入队,队列满了会怎样?
0

评论者:alexmiller

我对“已实现?”的实现基于Rich针对您的问题(来自内部聊天)的回答:“打开+未填充=false,否则=true”,我相信这就是已实现并反映在测试中的内容。这也比我只在实际关闭时实现这一点更有意义。

您的评论与其他“已实现?”的案例似乎准确,所以我同意这是一个问题。

能否更具体地说明实施协议?我猜测您特别指的是通道和缓冲区。任何线程都可以调用通道。M2MC使用互斥锁来保护其内部状态,并将调用传递到缓冲区。所有对缓冲区的调用都受到通道互斥锁的保护。M2MC在put和take列表中对挂起的put和take进行排队。这些受固定限制clojure.core.async.impl.protocols/MAX-QUEUE-SIZE(1024)的限制,在此点处将引发异常。

0

评论者:alexmiller

在ManyToManyChannel中使用现有异步结构对IDeref和IBlockingDeref进行概念性实现相对简单。

`
(deftype ManyToManyChannel

IDeref
(deref [this] (<!! this))

IBlockingDeref
(deref [this ms timeoutValue]

(alt!!
  this ([val _] val)
  (timeout ms) timeoutValue)))

`

但是,M2MC定义在clojure.core.async.impl.channels中。<!!、alt和timeout都在clojure.core.async中定义,这依赖于clojure.core.async.impl.channels,因此这里存在循环依赖问题。<!!和超时处理起来相对简单,可以通过查找如下延迟后的var来实现

`
(def ^:private <!!' (delay (find-var 'clojure.core.async/<!!)))

;; 然后
IDeref
(deref [this] (@<!!' this))
`

但是,我不太清楚如何用类似的alt!!来实现,它是一个围绕do-alt和alts!!的宏。

0

评论者:gshayban

不要依赖解决循环依赖。相反,创建一个共享的alt标志并将两个处理程序入队(链接:1)。fret将交付一个承诺,然后解引用承诺。

(链接:1) https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async.clj#L230-L231

0

评论者:alexmiller

新的补丁回到阻塞取消引用的先前实现(basically guts of <!!)并添加了基于alts的计时取消引用的新版本。

0

评论者:fogus

但是,我不太清楚如何用
alt!!来实现类似的操作,它是一个围绕do-alt和alts!!的宏。

我想知道以下方法是否可以解决 alts!! 问题

(def ^:private ^:macro alts!!' (deref (find-var 'clojure.core.async/alts!!)))

然后将其用于 IBlockingDeref 的 deref 实现。目前的代码很难理解,因为它使用了某些 core.async 的实现细节(实际上,同一代码)。而你的 IBlockingDeref.deref 实现非常清晰,但由循环依赖引发的实现则不然。不宜过多强调(我似乎一直在强调这一点),alts!! 对于这个实现来说是清晰的,但是使用内部构造则会模糊视线。如果可以的话,我更倾向于清晰性。

尽管如此,作为一名人类宏展开器,我最终还是理解了实现过程。

0
by

评论者:alexmiller

在我看来这不起作用。如果你有可行的方案,那将非常棒!

0
by
参考资料:[https://clojure.atlassian.net/browse/ASYNC-102](https://clojure.atlassian.net/browse/ASYNC-102)(由 stu 报告)
...