package netflix.ocelli.examples.rxnetty.http;
import io.netty.buffer.ByteBuf;
import io.reactivex.netty.protocol.http.client.HttpClient;
import io.reactivex.netty.protocol.http.client.events.HttpClientEventsListener;
import netflix.ocelli.Instance;
import netflix.ocelli.examples.rxnetty.http.HttpExampleUtils.*;
import netflix.ocelli.rxnetty.protocol.http.HttpLoadBalancer;
import rx.Observable;
import java.net.ConnectException;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;
import static io.netty.handler.codec.http.HttpResponseStatus.*;
import static netflix.ocelli.examples.rxnetty.http.HttpExampleUtils.*;
public final class RoundRobin {
private RoundRobin() {
}
public static void main(String[] args) {
Observable<Instance<SocketAddress>> hosts = newHostStreamWithCannedStatus(OK, SERVICE_UNAVAILABLE,
null/*Unavailable socket address*/);
HttpLoadBalancer<ByteBuf, ByteBuf> lb =
HttpLoadBalancer.<ByteBuf, ByteBuf>roundRobin(hosts, failureListener -> {
return new HttpClientEventsListener() {
@Override
public void onResponseHeadersReceived(int responseCode, long duration, TimeUnit timeUnit) {
if (responseCode == 503) {
// When throttled, quarantine.
failureListener.quarantine(1, TimeUnit.MINUTES);
}
}
@Override
public void onConnectFailed(long duration, TimeUnit timeUnit, Throwable throwable) {
// Connect failed, remove
failureListener.remove();
}
};
});
HttpClient.newClient(lb.toConnectionProvider())
.createGet("/hello")
.doOnNext(System.out::println)
.flatMap(resp -> {
if (resp.getStatus().code() != 200) {
return Observable.error(new InvalidResponseException());
}
return resp.getContent();
})
.retry((integer, throwable) -> throwable instanceof SocketException
|| throwable instanceof ConnectException
|| throwable instanceof InvalidResponseException)
.repeat(10)
.toBlocking()
.forEach(bb -> bb.toString(Charset.defaultCharset()));
}
}