【问题标题】:Any other examples of multi-state Agent programming in FSharp?FSharp 中的多状态代理编程的任何其他示例?
【发布时间】:2017-09-27 03:07:08
【问题描述】:

我正在研究具有多个状态的 F# 代理,即使用“let rec/and”关键字组合(根据 Expert F# 3.0 的“消息处理和状态机”)来提供多个异步块。到目前为止,我能找到的唯一例子是讨论过的“节流代理”here(也是 Fssnip.net)。是否有任何其他资源可用于学习此模式?

编辑:我的具体应用是一个有两种状态的代理,

| StartFeed rateMultiplier replychannel ->

     - replychannel out data values at a delay (provided with each value) 
       multiplied by rateMultiplier
     - loop by using  
       thisAgent.Post(StartFeed rateMultiplier replychannel)


| Pause -> 

我想提供一些方法来传递进给率乘数值,该值通过在“馈送”异步状态下传入的乘数增加/减少延迟,而不会中断值的馈送。我想这个问题可以归结为“你如何保持异步状态块主动循环,同时仍然知道新消息?”几乎就像跳过收件箱一样。接收异步等待,除非消息实际进入?收件箱.scan?

编辑 2:鉴于 MailboxProcessor 的消息队列方面,我可以看到代理接收并放入队列中的外部消息(具有不同的 rateMultiplier 值)将成功更改速率而不会中断数据流值了。任何关于“暂停”的建议仍将不胜感激。

【问题讨论】:

标签: asynchronous f# agent mailboxprocessor


【解决方案1】:

我找到了 Tomas Petricek 的条目https://github.com/tpetricek/FSharp.AsyncExtensions/blob/master/src/Agents/BlockingQueueAgent.fs,它为具有标准邮箱处理器队列的代理提供了一种方法来选择它将用于处理下一条传入消息的异步块(即,让代理'更改其状态'):

  • inbox.Receive() 用于“标准状态” - 代理的消息“收件箱”队列既不满也不空(状态 #1)
  • inbox.Scan() 用于空(状态#2)和满(状态#3)消息“收件箱”队列的“边缘”或限制情况

  • 代理(在三种状态中的任何一种)响应接收到的消息可以采取的操作被写为**不同的异步块,这些块被赋予了它们的自己的“和”异步块在代理的“let rec”循环中;我曾认为“让记录……和……”异步块仅限于具有消息接收功能(.Receive、.Scan 等),这是不正确的,它们可能是保持所需控制的任何异步块流程,如 'let rec...and...' 代理主体的下一个功能所示:

  • 一旦代理在 3 种状态中的任何一种状态下通过路由到适当的操作来响应新消息,该操作本身就会通过调用代理主体的另一个“和”异步块“让rec' 循环,一个 'chooseState()',一个 if/then 块,用于确定哪个状态将处理新消息,并从 3 个可用块中调用该 'and' 异步块。

这个例子似乎必不可少在演示惯用使用多状态代理主体构造,特别是如何结合消息接收、响应和循环控制三个功能作为单个 'let rec...and...and..." 构造的相互递归元素。

当然存在其他消息传递框架,但这是更复杂代理的通用逻辑/路由设计,无论框架如何,所以: 谢谢,托马斯。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-29
    • 2018-06-01
    • 1970-01-01
    • 2012-03-23
    • 2019-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多