Rx java 错误时可观察到的变化
错误时如何更改订阅服务器?我有一个冷流从数据库消费。请参见以下案例:Rx java 错误时可观察到的变化,rx-java,rx-java2,project-reactor,Rx Java,Rx Java2,Project Reactor,错误时如何更改订阅服务器?我有一个冷流从数据库消费。请参见以下案例: return coctailBundleStream .doOnNext(c -> { hostnames.add(c.get(KEY_HOSTNAME)); // [A] sendToOutboundQueue(c.get(KEY_CREDS)); archiveSentMessage(c.get(KEY_CREDS), c.get(KEY_
return coctailBundleStream
.doOnNext(c -> {
hostnames.add(c.get(KEY_HOSTNAME)); // [A]
sendToOutboundQueue(c.get(KEY_CREDS));
archiveSentMessage(c.get(KEY_CREDS), c.get(KEY_MESSAGE_ID));
})
.doOnComplete(this::saveCutOffTime)
.doOnError(e -> informUserImpactedHostnames(hostnames,
theRestOfHostnamesInside(credsXmlStream, e))) // I don't think this is right
.onErrorResumeNext(Flowable.empty())
.count();
我想发送受故障影响的所有主机名。但是,请看我上面的评论。我认为这是不对的,因为这条流被消耗了两次。例如,如果theRestOfHostnamesInside
的实现是credstream.map(c->c.getHostname()),e)
我认为,理想情况下,错误处理程序应该使用另一个订阅继续流,该订阅将其余主机名提取到一个列表中,然后将该列表与前一个列表一起附加(请参见标有[a]的行)。
onErrorResumeNext
应该用于提供您想要回退的可流动主机名
然而,主要的困难是避免重复。如果源代码如您所说是冷的,那么您将重新执行一个DB请求,并且如果最初订阅的序列在出错之前发出了一些数据,那么相同的数据将重新发出
您可以通过在onErrorResumeNext
之后链接distinct
来缓解这种情况(您应该能够提供键选择器来指示如何检测重复项)。但您必须确保使用的条件不会将源中的两个元素标记为重复项(以便仅消除重试创建的重复项)
另一种方法是将自己已经处理过的密钥存储在一个集合中,并在onErrorResumeNext
中过滤掉这些密钥,但您必须确保所述集合特定于subscribe
在count()下游生成的每个subscribe
。。。所以没那么容易。onErrorResumeNext
应该用于提供您想要回退的可流动性
然而,主要的困难是避免重复。如果源代码如您所说是冷的,那么您将重新执行一个DB请求,并且如果最初订阅的序列在出错之前发出了一些数据,那么相同的数据将重新发出
您可以通过在onErrorResumeNext
之后链接distinct
来缓解这种情况(您应该能够提供键选择器来指示如何检测重复项)。但您必须确保使用的条件不会将源中的两个元素标记为重复项(以便仅消除重试创建的重复项)
另一种方法是将自己已经处理过的密钥存储在一个集合中,并在onErrorResumeNext
中过滤掉这些密钥,但您必须确保所述集合特定于subscribe
在count()下游生成的每个subscribe
。。。所以没那么容易。你可以在平面地图内完成
Observable.fromIterable(yourList)
.flatMap(x ->{
Observable.just(x)
.map(data -> yourNormalSave(data))
.onErrorReturn(errorResult)
})
.subscribe(result ->{
if(result != errorResult)
count++;
eles{
//error received here
}
}
);
所以在flatMap内部,如果您遇到错误,它会将其更改为正常类型,但下游对此一无所知。因此,您的下游用户也在onNext中使用它们。你可以正确地做它,而不是x->Observable。只是(x)
我只是把它们作为一个例子放在那里。你可以在平面图中做它
Observable.fromIterable(yourList)
.flatMap(x ->{
Observable.just(x)
.map(data -> yourNormalSave(data))
.onErrorReturn(errorResult)
})
.subscribe(result ->{
if(result != errorResult)
count++;
eles{
//error received here
}
}
);
所以在flatMap内部,如果您遇到错误,它会将其更改为正常类型,但下游对此一无所知。因此,您的下游用户也在onNext中使用它们。您可以正确地执行它,而不是x->Observable。只是(x)
我只是把它们作为一个示例。我不喜欢重新执行相同的DB请求。这对我来说似乎效率不高。这取决于最初的错误是什么,但你可以回退到第二个序列,只查询丢失的键。。。由于onErrorResumeNext
将错误序列(如果有)中的数据与回退序列中的数据连接起来,这符合要求。我不喜欢重新执行相同的DB请求。这对我来说似乎效率不高。这取决于最初的错误是什么,但你可以回退到第二个序列,只查询丢失的键。。。由于onErrorResumeNext
将错误序列(如果有)中的数据与回退序列中的数据连接起来,因此这符合要求