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?}}的定义进行说明以支持这种新情况。 Clojure中{{realized?}}的其他用法都保证后续的deref将立即填充,但如果另一个消费者拿走了这个值,通道可能不会这样。

解决这个问题后,我在筛选这件事之前需要为core.async实现协议提供更好的文档字符串。对线程的使用有什么保证?工作在哪里排队?如果队列已满会怎样?
0

评论者: alexmiller

我的实现方式“已实现?”是基于Rich对您问题的回复(来自内部聊天):“打开+空=false,否则=true”。我相信这是实现并反映在测试中的内容。这比仅在关闭时实现更有意义。

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

请具体说明哪种实现协议?我猜您特别指的是通道和缓冲区。任何线程都可能调用通道。M2MC使用互斥锁保护其内部状态,并将调用传递给缓冲区。所有对缓冲区的调用都由通道互斥锁保护。M2MC将在“放入”和“取出”列表中入队待处理“放入”和“取出”。这些受限于clojure.core.async.impl.protocols/MAX-QUEUE-SIZE(1024)的固定限制,在该点将抛出异常。

0

评论者: alexmiller

在许多多通道中使用现有的异步结构来实现IDeref和IBlockingDeref的概念化实现相对简单

`
(deftype ManyToManyChannel
#_existing_code...
IDeref
(deref [this] (<!! this))

IBlockingDeref
(deref [this ms timeoutValue]

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

`

然而,M2MC在clojure.core.async.impl.channels中定义。<!!、alt(image: )和timeout都在clojure.core.async中定义,clojure.core.async依赖于clojure.core.async.impl.channels,因此这里存在循环依赖问题。通过查找delay后面的var,<!!和超时相对容易处理,如下所示

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

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

然而,我在如何使用alt!!实现等效方案上有点困惑,它是一个围绕do-alt和alts(image: )的宏。

0

评论者:gshayban

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

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

0

评论者: alexmiller

New patch goes back to prior implementation of blocking deref (basically guts of <!!) and adds new alts-based version of timed deref.

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

评论者: alexmiller

但这似乎不起作用。如果你有其他有效的方法,那将是非常棒的!

0
...