我正在学习 F# 代理(MailboxProcessor
).
我正在处理一个相当非传统的问题。
- 我有一名代理人(
dataSource
)这是流数据的来源。数据必须由一系列代理进行处理(dataProcessor
)。我们可以考虑dataProcessor
作为某种跟踪设备。
- 数据流入的速度可能比数据传输的速度快
dataProcessor
也许能够处理其输入。
- 有一些延迟是可以的。但是,我必须确保代理始终保持其工作状态,并且不会堆积在过时的观察结果中
我正在探索解决这个问题的方法。
The 第一个想法是要实施一个stack http://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29(后进先出)在dataSource
. dataSource
将发送最新的观察结果dataProcessor
可以接收和处理数据。这个解决方案可能有效,但可能会变得复杂dataProcessor
可能需要被阻止并重新激活;并将其状态传达给dataSource
,导致双向通信问题。这个问题可能归结为blocking queue
in the 消费者-生产者问题 http://msdn.microsoft.com/en-us/library/vstudio/hh297096%28v=vs.100%29.aspx但我不确定..
The 第二个想法就是拥有dataProcessor
负责消息排序。在这个架构中,dataSource
将简单地发布更新dataProcessor
的队列。dataProcessor
将使用Scan
获取队列中可用的最新数据。这可能是要走的路。但是,我不确定在当前的设计中是否MailboxProcessor
可以清除消息队列,删除较旧的过时消息。此外,here https://stackoverflow.com/questions/4880171/how-to-use-tryscan-in-f-properly,记载为:
不幸的是,当前版本的 F# 中的 TryScan 函数是
以两种方式破碎。首先,重点是指定超时
但实施实际上并没有遵守它。具体来说,
不相关的消息会重置计时器。其次,与其他扫描一样
函数中,消息队列在锁下进行检查,以防止任何
在扫描期间禁止其他线程发帖,这可以是
任意长的时间。因此,TryScan 函数本身
往往会锁定并发系统,甚至可能导致死锁
因为调用者的代码是在锁内评估的(例如发布
从函数参数到 Scan 或 TryScan 可能会使代理陷入僵局
当锁下的代码阻塞等待获取锁时
已经在下)。
最新的观察结果反弹可能是一个问题。
这篇文章的作者 @Jon Harrop 建议
我设法围绕它进行架构设计,最终的架构实际上更好。本质上,我渴望Receive
所有消息和过滤器都使用我自己的本地队列。
这个想法确实值得探索,但是在开始使用代码之前,我欢迎一些关于如何构建我的解决方案的意见。
谢谢。
听起来您可能需要邮箱处理器的破坏性扫描版本,我在您可能感兴趣的博客系列中使用 TPL Dataflow 实现了此功能。
我的博客目前已关闭以进行维护,但我可以向您指出 Markdown 格式的帖子。
Part1 https://github.com/MoiraeSoftware/moiraesoftware.github.com/blob/source/source/_posts/2012-01-22-FSharp-Dataflow-agents-I.markdown
Part2 https://github.com/MoiraeSoftware/moiraesoftware.github.com/blob/source/source/_posts/2012-01-24-FSharp-Dataflow-agents-II.markdown
Part3 https://github.com/MoiraeSoftware/moiraesoftware.github.com/blob/source/source/_posts/2012-02-19-fsharp-dataflow-agents-iii.markdown
您还可以查看以下代码github https://github.com/7sharp9/FSharpDataflow
我还写了关于我潜伏的恐惧中的扫描问题post https://github.com/MoiraeSoftware/moiraesoftware.github.com/blob/source/source/_posts/2012-07-15-the-lurking-horror.markdown
希望有帮助...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)