Haskell 非确定交错导管源

Haskell 非确定交错导管源,haskell,conduit,Haskell,Conduit,我希望看到一个不确定的源交叉操作,类型签名如下 interleave :: WhateverIOMonadClassItWouldWant m => [(k, Source m a)] -> Source m (k, a) 使用案例是,我有一个p2p应用程序,该应用程序保持与网络上许多节点的开放连接,它主要只是坐在那里等待来自其中任何一个节点的消息。当消息到达时,它不关心它来自哪里,但需要尽快处理消息。理论上,这种应用程序(至少在用于类似套接字的源时)可以完全绕过GHC的IO管理器

我希望看到一个不确定的源交叉操作,类型签名如下

interleave :: WhateverIOMonadClassItWouldWant m => [(k, Source m a)] -> Source m (k, a)
使用案例是,我有一个p2p应用程序,该应用程序保持与网络上许多节点的开放连接,它主要只是坐在那里等待来自其中任何一个节点的消息。当消息到达时,它不关心它来自哪里,但需要尽快处理消息。理论上,这种应用程序(至少在用于类似套接字的源时)可以完全绕过GHC的IO管理器,直接运行select/epoll/etc.调用,但我并不特别关心它是如何实现的,只要它能够工作

导管有可能这样吗?一种不太通用但可能更可行的方法可能是编写一个[k,Socket]->Source mk,ByteString函数,用于处理所有套接字上的接收

我注意到管道中的ResumableSource操作,但他们似乎都想知道某个特定的接收器,这感觉有点像抽象泄漏,至少对于这个操作来说是这样。

是的,这是可能的

您可以通过分叉线程来轮询一组源,而无需阻塞,在每个线程中,您可以将源与一个接收器配对,该接收器将输出发送到某个并发通道:

concur :: (WhateverIOMonadClassItWouldWant m) => TChan a -> Sink a m r
。。。然后定义一个从该通道读取的源:

synchronize :: (WhateverIOMonadClassItWouldWant m) => TChan a -> Source a m r
请注意,这与分叉线程以轮询套接字本身没有什么不同,但对于可能希望使用他们定义的源轮询套接字以外的其他内容的其他导管用户来说,这是非常有用的,因为它更通用

如果将这些功能组合到一个函数中,那么调用的整体API将如下所示:

poll :: (WhateverIOMonadClassItWouldWant m) => [Source a m r] -> m (Source a m r)

。。。但是,如果您愿意,您仍然可以插入这些ks。

stm导管包提供了与您所寻找的类似(尽管不完全相同)的功能。这可能是一个很好的起点。

与使用forkIO和封装Chan/TChan的源代码的简单解决方案相比,您需要多快的性能?我不一定需要高性能,我预计最多可以连接到1000个这样的同行,但我也对这些类似于迭代的抽象感兴趣,我想知道是否有可能通过导管提供此类操作。对于某些类型的网络协议来说,这似乎是一个相当常见的用例。我相信,如果不直接使用select或epoll或通过某个软件包,事件管理器将与您所能获得的最接近。我不认为有一个从事件管理器中暴露出来的轮询接口。如果它这样做了,那么它就不是一个事件管理器了。无论如何,在大多数设计中,你会得到一些线程和通道。我要做的是从一个封装有界TChan的源代码开始,首先为每个连接分叉一个线程。如果性能需要,请转到事件管理器。如果您仍然有问题,那么总会有FFI。这是可行的,但是如果我们想寻求一种避免GHC线程和通道开销的方法,GHC事件管理器至少有一个API。真正的问题是导管源是否可以将值推出,或者接收器是否在概念上将值拉出。在前一种情况下,GHC.Event API可以轻松地允许一个高效的[k,Socket]->Source mk,ByteString组合器。如果它们是被动的,那么我们需要对结果进行排队。如果您需要避免线程和回调,那么您可能必须使用轮询循环来保持源拉动模型。我至少会从forkIO/Chan的简单方法开始,设定一个基准,并在必要时从那里开始工作。接受Michael的答案。它和我描述的一样。有人能详细解释一下为什么mergeSources的类型将它处理的源的monad参数限制为ResourceT m的形式而不是任何MonadResource实例吗?我看不出原因,值得向维护人员提出问题。在调用mergeSources时,您可能可以使用liftResourceT来解决这个问题。感谢@MichaelSnoyman,我在这里创建了一个问题:我还能够根据您的建议找到一个合适的包装器,将整个类型更改为不显式提及ResourceT,这满足了我的需要。这现在在stm导管2.5.1中实现。