package netflix.ocelli.examples.rxnetty.http; import io.netty.buffer.ByteBuf; import io.reactivex.netty.protocol.http.client.HttpClient; import netflix.ocelli.Instance; import netflix.ocelli.examples.rxnetty.http.HttpExampleUtils.*; import netflix.ocelli.rxnetty.protocol.http.HttpLoadBalancer; import netflix.ocelli.rxnetty.protocol.http.WeightedHttpClientListener; 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 netflix.ocelli.examples.rxnetty.http.HttpExampleUtils.*; public final class RandomWeighted { private RandomWeighted() { } public static void main(String[] args) { Observable<Instance<SocketAddress>> hosts = newHostStreamWithCannedLatencies(1L, 2L); HttpLoadBalancer<ByteBuf, ByteBuf> lb = HttpLoadBalancer.<ByteBuf, ByteBuf>weigthedRandom(hosts, failureListener -> { return new WeightedHttpClientListener() { private volatile int weight; @Override public int getWeight() { return weight; } @Override public void onResponseHeadersReceived(int responseCode, long duration, TimeUnit timeUnit) { /* This is just a demo for how to wire the weight of an instance to the load balancer, it * certainly is not the algorithm to be used in real production applications. */ weight = (int) (Long.MAX_VALUE - duration); // High latency => low weight 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())); } }