我有一个能够从中断中恢复的网络客户端,但在重试时需要最后一条消息。
Kotlin的例子:
fun requestOrResume(last: Message? = null): Flowable<Message> =
Flowable.create({ emitter ->
val connection = if (last != null)
client.start()
else
client.resumeFrom(last.id)
while (!emitter.isDisposed) {
val msg = connection.nextMessage()
emitter.onNext(msg)
}
}, BackpressureStrategy.MISSING)
requestOrResume()
.retryWhen { it.flatMap { Flowable.timer(5, SECONDS) } }
// how to pass the resume data when there is a retry?
问题:正如您所看到的,我需要最后收到的消息才能准备简历呼叫。如何跟踪它,以便在重试时可以进行恢复请求?
一种可能的解决方案可能是创建一个持有者类,它只保存对最后一条消息的引用,并在收到新消息时更新。这样,当重试时,可以从持有者获得最后的消息。例如:
class MsgHolder(var last: Message? = null)
fun request(): Flowable<Message> {
val holder = MsgHolder()
return Flowable.create({ emitter ->
val connection = if (holder.last != null)
client.start()
else
client.resumeFrom(holder.last.id)
while (!emitter.isDisposed) {
val msg = connection.nextMessage()
holder.last = msg // <-- update holder reference
emitter.onNext(msg)
}
}, BackpressureStrategy.MISSING)
}
我认为这可能会有效,但感觉就像是黑客攻击(线程同步问题?)。
是否有更好的方法来跟踪状态,以便可以重试?
答案 0 :(得分:1)
请注意,除非你在最后一个元素周围重新抛出一个包装器(在功能上与你现有的&#34; hack&#34; -ish解决方案没有太大的区别,但uglier imo),没有错误处理操作符可以恢复最后一个元素一些外部帮助,因为他们只能访问private final ArrayList<RadioStation> namesOfStationsOfTopHitsStations = new ArrayList<>();
private final ArrayList<RadioStation> namesOfStationsOfHipHopStations = new ArrayList<>();
private final ArrayList<RadioStation> namesOfStationsOfRockStations = new ArrayList<>();
private final ArrayList<RadioStation> namesOfStationsOfElectronicStations = new ArrayList<>();
private final ArrayList<RadioStation> namesOfStationsOf80sStations = new ArrayList<>();
private final ArrayList<RadioStation> namesOfStationsOf90sStations = new ArrayList<>();
private final ArrayList<RadioStation> collegeRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> rockRadioStations = new ArrayList<>();
//radiostations by countries
private final ArrayList<RadioStation> namesOfStationsOfAustrianStations = new ArrayList<>();
private final ArrayList<RadioStation> namesOfStationsOfBelarusianStations = new ArrayList<>();
private final ArrayList<RadioStation> namesOfStationsOfAlbanianStations = new ArrayList<>();
private final ArrayList<RadioStation> belgiumRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> bulgarianRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> croatianRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> cyprusRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> czechRepublicRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> denmarkRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> estonianRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> finlandRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> franceRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> germanianRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> greeceRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> hungarianRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> irishRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> italianRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> latvianRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> lithuanianRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> netherlandsRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> norwayRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> polishRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> portugalRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> romanianRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> russianRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> serbianRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> slovakianRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> slovenianRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> spanishRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> swedishRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> switzerlandRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> unitedKingdomRadioStations = new ArrayList<>();
private final ArrayList<RadioStation> ukrainianRadioStations = new ArrayList<>();
private final ArrayList<ArrayList<RadioStation>> totalStations = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Handler handler = new Handler();
new Thread(new Runnable() {
@Override
public void run() {
totalStations.add(namesOfStationsOfTopHitsStations);
totalStations.add(namesOfStationsOfHipHopStations);
totalStations.add(namesOfStationsOfRockStations);
totalStations.add(namesOfStationsOfElectronicStations );
totalStations.add(namesOfStationsOf80sStations );
totalStations.add(namesOfStationsOf90sStations );
totalStations.add(collegeRadioStations );
totalStations.add(rockRadioStations );
totalStations.add(namesOfStationsOfAlbanianStations );
totalStations.add(namesOfStationsOfAustrianStations );
totalStations.add(namesOfStationsOfBelarusianStations );
totalStations.add(belgiumRadioStations );
totalStations.add(bulgarianRadioStations );
totalStations.add(croatianRadioStations );
totalStations.add(cyprusRadioStations );
totalStations.add(czechRepublicRadioStations );
totalStations.add(denmarkRadioStations );
totalStations.add(estonianRadioStations );
totalStations.add(finlandRadioStations );
totalStations.add(franceRadioStations );
totalStations.add(germanianRadioStations );
totalStations.add(greeceRadioStations );
totalStations.add(hungarianRadioStations );
totalStations.add(irishRadioStations );
totalStations.add(italianRadioStations );
totalStations.add(latvianRadioStations );
totalStations.add(lithuanianRadioStations );
totalStations.add(netherlandsRadioStations );
totalStations.add(norwayRadioStations );
totalStations.add(polishRadioStations );
totalStations.add(portugalRadioStations );
totalStations.add(romanianRadioStations );
totalStations.add(russianRadioStations );
totalStations.add(serbianRadioStations );
totalStations.add(slovakianRadioStations );
totalStations.add(slovenianRadioStations );
totalStations.add(spanishRadioStations );
totalStations.add(swedishRadioStations );
totalStations.add(switzerlandRadioStations );
totalStations.add(unitedKingdomRadioStations );
totalStations.add(ukrainianRadioStations );
final ArrayList<String> genresList = new ArrayList<>();
genresList.add("Top Hits");
genresList.add("Hip hop");
genresList.add("Rock");
genresList.add("Electronic");
genresList.add("80s");
genresList.add("90s");
genresList.add("College radio");
genresList.add("Classic Rock radio");
genresList.add("Albanian radio");
genresList.add("Austrian radio");
genresList.add("Belarusian radio");
genresList.add("Belgium radio");
genresList.add("Bulgarian radio");
genresList.add("Croatian radio");
genresList.add("Cyprus radio");
genresList.add("Czech radio");
genresList.add("Denmark radio");
genresList.add("Estonian radio");
genresList.add("Finland radio");
genresList.add("France radio");
genresList.add("Germany radio");
genresList.add("Greece radio");
genresList.add("Hungarian radio");
genresList.add("Irish radio");
genresList.add("Italian radio");
genresList.add("Latvian radio");
genresList.add("Lithuanian radio");
genresList.add("Netherlands radio");
genresList.add("Norway radio");
genresList.add("Polish radio");
genresList.add("Portugal radio");
genresList.add("Romanian radio");
genresList.add("Russian radio");
genresList.add("Serbian radio");
genresList.add("Slovakian radio");
genresList.add("Slovenian radio");
genresList.add("Spanish radio");
genresList.add("Swedish radio");
genresList.add("Switzerland radio");
genresList.add("United Kingdom radio");
genresList.add("Ukrainian radio");
createRadioStations1();
createRadioStations2();
createRadioStations3();
createRadioStations4();
createRadioStations5();
createRadioStations7();
handler.post(new Runnable() {
@Override
public void run() {
for(int i = 0; i<totalStations.size(); i++){
System.out.println(genresList.get(i) + " is curently iterated");
for(int j = 0; j<totalStations.get(i).size(); j++){
int index = genresList.get(i).indexOf(" ");
if(index != -1){
System.out.println("RadioStation " + "radio" + (genresList.get(i).substring(0, index) + j + " = new RadioStation();"));
} else {
System.out.println("RadioStation " + "radio" + (genresList.get(i) + j + " = new RadioStation();"));
}
System.out.println("radio" + genresList.get(i) + j + ".mCustom = false;");
System.out.println("radio" + genresList.get(i) + j + ".mName = \"" + totalStations.get(i).get(j).mName + "\";");
System.out.println("radio" + genresList.get(i) + j + ".mUrl = \"" + totalStations.get(i).get(j).mUrl + "\";");
}
}
}
});
}
}).start();
}
的流。相反,看看以下递归方法是否适合您的需求:
Throwable
最大的区别是使用fun retryWithLast(seed: Flowable<Message>): Flowable<Message> {
val last$ = seed.last().cache();
return seed.onErrorResumeNext {
it.flatMap {
retryWithLast(last$.flatMap {
requestOrResume(it)
})
}
};
}
retryWithLast(requestOrResume());
缓存Observable中最后一次尝试的尾随值,而不是在值中手动执行此操作。另请注意,如果后续尝试继续失败,错误处理程序中的递归意味着cache
将继续扩展流。
答案 1 :(得分:0)
Take a close look to buffer()
operator: link中
您可以像这样使用它:
requestOrResume()
.buffer(2)
从现在起,您的Flowable
将返回List<Message>
两个最新对象