[英]In Rx.Net how can I implement an observable feedback loop until the feedback is exhausted?
我有以下API:
IObservable<IList<SqlDataRecord>> WriteToDBAndGetFailedSource(SqlConnection conn, IList<SqlDataRecord> batch)
它试图将批处理写入数据库。 如果失败,则返回整个批处理,否则返回的observable为空。
我也有一个产生批次的来源:
IObservable<IList<SqlDataRecord>> GetDataSource(string filePath, int bufferThreshold)
现在,我可以像这样组合它们:
var failedBatchesSource = GetDataSource(filePath, 1048576)
.Select(batch => WriteToDBAndGetFailedSource(conn, batch))
.Merge(100);
这将编写所有批次(最多100个并发)并返回可观察到的失败批次。
我真正想要的是在一段暂停之后将失败的批次送回批次的来源,可能是在原始来源仍在生产批次时。 当然,我可以这样写:
var failedBatchesSource = GetDataSource(filePath, 1048576)
.Select(batch => WriteToDBAndGetFailedSource(conn, batch))
.Merge(100)
.Select(batch => WriteToDBAndGetFailedSource(conn, batch))
.Merge(100);
但当然,这是错误的,因为:
一旦我收集了所有的失败并在循环中重新开始,我也可以打破可观察的monad:
var src = GetDataSource(filePath, 1048576);
for (;;)
{
var failed = await src
.Select(batch => WriteToDBAndGetFailedSource(conn, batch))
.Merge(100)
.ToList();
if (failed.Count == 0)
{
break;
}
src = failed.ToObservable();
}
但是我想知道我是否可以在可观察的monad中保持更好的状态。
我认为这可能会成功
public static IObservable<T> ProcessAll<T>(this IObservable<T> source, Func<T, IObservable<T>> processor, int mergeCount, TimeSpan failureDelay)
{
return Observable.Create<T>(
observer =>
{
var failed = new Subject<T>();
return source.Merge(failed)
.Select(processor)
.Merge(mergeCount)
.Delay(failureDelay)
.Subscribe(failed.OnNext, observer.OnError, observer.OnCompleted);
});
}
并像这样使用它:
GetDataSource(filePath, 1048576)
.ProcessAll(batch => WriteToDBAndGetFailedSource(conn, batch), 100, TimeSpan.FromMilliseconds(500))
.Subscribe();
ProcessAll是一个可怕的名字,但它是星期五晚上,我想不出更好的名字。
使用Observable.Buffer。 这允许您缓冲,直到您有100条记录要发送,或者直到X时间已经过去。
或者, Observable.Interval将只触发每个X时间跨度。 您可以在处理发布事件时添加并发限制。
只要有要发布的对象,这些中的任何一个都应该重复发射。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.