I am trying to implement a retry mechanism for HTTP request with a HTTPClient library. For the retry mechanism, I have a list of website to try and I will try each website for retries
times. The process ends when I receive a status 200
from any of the requests.
My idea is to use a boolean requestSuccess
and a label requestLabel
. I will set requestSuccess = true
and break the requestLabel
when I receive a status 200
. However, variable must be (effectively) final
and break
label is not available inside lambda expression.
Is there any workaround to implement such retry mechanism?
boolean requestSuccess = false;
requestLabel:
for(String site: sites) {
for(int i = 0; i < retries; i++) {
client.request(site, data, requestOptions, (err, res, content) -> {
if(err == null) {
requestSuccess = true;
break requestLabel;
} else {
log(...);
}
})
}
}
if(!requestSuccess) {
log("request failed");
}
One possible answer
Inspired by a submitted then deleted answer, I can use a wrapped-class-like solution. I think it would work, but it seems dirty?
boolean[] requestSuccess = new boolean[1];
requestLabel:
for(String site: sites) {
for(int i = 0; i < retries; i++) {
if(requestSuccess[0] == true) {
break requestLabel;
}
client.request(site, data, requestOptions, (err, res, content) -> {
if(err == null) {
requestSuccess[0] = true;
} else {
log(...);
}
})
}
}
if(!requestSuccess) {
log("request failed");
}
A lambda gets turned into it's own class under the hood. It would be as if you have two classes as far as the java interpreter is concerned.
class Main {
public void runstuff() {
labelX:
for(...) {
client.request(new Main$Foo().xyz(.....));
}
}
class Foo {
public xyz(....) {
break labelX; // There is no labelX to break to here in Foo.xyz
}
}
}