[英]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
我已經mapAsync
了mapAsync
和AwaitObservable
:理想情況下它們將由某個庫提供,到目前為止我找不到它。
額外要求:
應該按順序執行操作,以便在處理上一個事件時緩沖后續事件。
如果某個操作引發錯誤,我希望我的處理器完成。 否則,它永遠不會完成。
應該尊重通過Async.Start
傳遞的取消令牌。
關於我應該使用的圖書館的任何提示?
由於您希望將基於推送的模型( IObservable<>
)轉換為基於拉的( Async<>
),因此您需要排隊以緩沖來自observable的數據。 如果隊列大小有限 - 哪個tbh。 應該是為了使整個管道安全,不要過度內存 - 然后還需要緩沖區溢出的策略。
MailboxProcessor<>
和自定義observable,它會將數據發布到它。 由於MP是本機F#actor實現,因此它能夠使用隊列進行有序處理以緩沖峰值。 另一種選擇是使用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.