信息:
该方法的目的是从流中获取秘密,从流中获取uri。然后使用秘密和一些其他参数type
和name
点击uri以获取一些数据。
Secrets.GetSecret()
是IObservable<string>
而Urls.GetHostUrl()
是IObservable<Uri>
问题
我遇到的问题是,如果dataFetcher.GetFromUrl
调用抛出异常,则observable终止。 RetryAfterDelay
扩展方法似乎根本不起作用。
我希望能够捕获并记录异常,但理想情况下不能使用observable终止。或者如果它必须终止然后重新订阅原始流,那么它的行为就好像它已经记录/吞下了异常。
原因是网络/主机不是最稳定的,因此有时它可能会出错。
方式
private IObservable<string> GetFromHostUrl(string type, string name, int retryTime)
{
return Observable.Interval(TimeSpan.FromSeconds(retryTime), schedulerProvider.Default).StartWith(-1L)
.CombineLatest(Observable.Defer(() => Secrets.GetSecret()),
Urls.GetHostUrl(),
(_, secret, hostUrl) => dataFetcher.GetFromUrl(hostUrl, type, name, secret).Result)
.Do(s =>
{
// log success
},
e =>
{
// log failure
})
.DistinctUntilChanged()
.RetryAfterDelay(TimeSpan.FromSeconds(retryTime), schedulerProvider.Default)
.Replay(1)
.RefCount();
}
扩展方法
// c/o: http://stackoverflow.com/questions/18978523/write-an-rx-retryafter-extension-method
public static class ExtensionMethods
{
private static IEnumerable<IObservable<TSource>> RepeateInfinite<TSource>(IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
{
// Don't delay the first time
yield return source;
while (true)
{
yield return source.DelaySubscription(dueTime, scheduler);
}
}
public static IObservable<TSource> RetryAfterDelay<TSource>(this IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
{
return RepeateInfinite(source, dueTime, scheduler).Catch();
}
}
答案 0 :(得分:0)
听起来像是Retry的教科书示例。
public static IObservable<TSource> RetryAfterDelay<TSource>(this IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
{
return RepeateInfinite(source, dueTime, scheduler).Retry();
}