簡體   English   中英

在F#中混合使用IObservable和Async <'a>

[英]Mixing IObservable and Async<'a> in F#

我有一個由庫提供的IObservable ,它監聽來自外部服務的事件:

let startObservable () : IObservable<'a> = failwith "Given"

對於每個收到的事件,我想執行一個返回Async的動作:

let action (item: 'a) : Async<unit> = failwith "Given"

我正在嘗試實現一個處理器

let processor () : Async<unit> =
    startObservable()
    |> Observable.mapAsync action
    |> Async.AwaitObservable

我已經mapAsyncmapAsyncAwaitObservable :理想情況下它們將由某個庫提供,到目前為止我找不到它。

額外要求:

  • 應該按順序執行操作,以便在處理上一個事件時緩沖后續事件。

  • 如果某個操作引發錯誤,我希望我的處理器完成。 否則,它永遠不會完成。

  • 應該尊重通過Async.Start傳遞的取消令牌。

關於我應該使用的圖書館的任何提示?

由於您希望將基於推送的模型( IObservable<> )轉換為基於拉的( Async<> ),因此您需要排隊以緩沖來自observable的數據。 如果隊列大小有限 - 哪個tbh。 應該是為了使整個管道安全,不要過度內存 - 然后還需要緩沖區溢出的策略。

  1. 一種方法是實現一個MailboxProcessor<>和自定義observable,它會將數據發布到它。 由於MP是本機F#actor實現,因此它能夠使用隊列進行有序處理以緩沖峰值。
  2. 另一種選擇是使用FSharp.Control.AsyncSeq (特別是AsyncSeq.ofObservableBuffered函數),它將observable轉換為基於pull的async可枚舉 - 在它下面使用第一點的郵箱處理器:

     startObservable() |> AsyncSeq.ofObservableBuffered |> AsyncSeq.iterAsync action 

Hopac可以輕松地與IObservables互操作您可以使用Job.toAsync將Hopac Jobs轉換為Async

open System
open Hopac

let startObservable () : IObservable<'a> = failwith "Given"

let action (item: 'a) : Job<unit> = failwith "Given"

let processor () : Job<unit> =
    startObservable()
    |> Stream.ofObservable
    |> Stream.mapJob action
    |> Stream.iter

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM