All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.wildfly.httpclient.common.HostPool Maven / Gradle / Ivy

Go to download

This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up with different versions on classes on the class path).

There is a newer version: 34.0.0.Final
Show newest version
/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2017 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.wildfly.httpclient.common;

import java.net.InetAddress;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;

/**
 * A host pool is defined as one or more hosts that are are serving
 * the same back end applications.
 * 

* For hosts to be in the same host pool it must be possible to make an invocation against any host * interchangeably. In general the connection pool will only use a single host at a time, however if the * connection fails it will attempt to use other hosts in the pool. *

* In a lot of cases this will only contain a single host, however if there are multiple load balancer hosts * that service the same underlying application then this class allows for invocations to be directed to either * if one falls over. *

* This class is also DNS load balancing aware. If there are multiple IP's for a given URL the different URL's will * be added to the rotation. *

* This host pool will attempt to simply use a single address, if it is notified of failure on that address it will * instead select a different URI. If there are multiple addresses per URI then the next time the URI is selected * it will attempt to use a new address. * * * @author Stuart Douglas */ public class HostPool { private final URI uri; private volatile InetAddress[] addresses; private volatile int currentAddress; private final AtomicLong failureCount = new AtomicLong(); public HostPool(URI uri) { this.uri = uri; } public AddressResult getAddress() { return new AddressResult(failureCount.get()); } private InetAddress getAddressImpl() throws UnknownHostException { while (true) { InetAddress[] addresses = this.addresses; int currentAddress = this.currentAddress; if (addresses == null) { synchronized (this) { if ((addresses = this.addresses) == null) { addresses = InetAddress.getAllByName(uri.getHost()); InetAddress primary = InetAddress.getByName(uri.getHost()); List filtered = new ArrayList<>(); //TODO: how to we handle addresses of different classes? //at the moment we only take addresses of the same type that is returned from getByName for(InetAddress a : addresses) { if(primary.getClass().isAssignableFrom(a.getClass())) { filtered.add(a); } } addresses = this.addresses = filtered.toArray(new InetAddress[filtered.size()]); } this.currentAddress = currentAddress = new Random().nextInt(this.addresses.length); } } if (currentAddress >= addresses.length) { continue; //minor chance of a race, as the address list and current address are not invoked atomically just re-invoke } return addresses[currentAddress]; } } public URI getUri() { return uri; } private void markError() { synchronized (this) { int current = currentAddress; current++; if (current == addresses.length) { current = 0; } this.currentAddress = current; } } public class AddressResult { private final long failCount; public AddressResult(long failCount) { this.failCount = failCount; } public InetAddress getAddress() throws UnknownHostException { return getAddressImpl(); } public URI getURI() { return uri; } public void failed() { markError(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy