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

com.elastisys.scale.cloudpool.commons.basepool.poolfetcher.impl.RetryingPoolFetcher Maven / Gradle / Ivy

package com.elastisys.scale.cloudpool.commons.basepool.poolfetcher.impl;

import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

import com.elastisys.scale.cloudpool.api.CloudPoolException;
import com.elastisys.scale.cloudpool.api.types.Machine;
import com.elastisys.scale.cloudpool.api.types.MachinePool;
import com.elastisys.scale.cloudpool.commons.basepool.config.RetriesConfig;
import com.elastisys.scale.cloudpool.commons.basepool.driver.CloudPoolDriver;
import com.elastisys.scale.cloudpool.commons.basepool.poolfetcher.FetchOption;
import com.elastisys.scale.cloudpool.commons.basepool.poolfetcher.PoolFetcher;
import com.elastisys.scale.commons.json.types.TimeInterval;
import com.elastisys.scale.commons.net.retryable.Retryable;
import com.elastisys.scale.commons.net.retryable.Retryers;
import com.elastisys.scale.commons.util.time.UtcTime;

/**
 * A {@link PoolFetcher} that synchronously "calls through" to the cloud
 * provider API to get the {@link MachinePool} on each invocation and uses a
 * configurable number of retries (with exponential back-off) to handle faults.
 */
public class RetryingPoolFetcher implements PoolFetcher {

	/** A cloud-specific management driver for the cloud pool. */
	private final CloudPoolDriver cloudDriver;

	/**
	 * Maximum number of retries to make on failed attempts to fetch pool
	 * members.
	 */
	private final int maxRetries;
	/** Initial delay to use in exponential back-off on retries. */
	private final TimeInterval initialBackoffDelay;

	/**
	 * Creates a {@link RetryingPoolFetcher} that will fetch machine pool
	 * members with the given {@link CloudPoolDriver} and retry handling.
	 *
	 * @param cloudDriver
	 *            A cloud-specific management driver for the cloud pool.
	 * @param retriesConfig
	 *            Retry handling when fetching pool members from the cloud API
	 *            fails.
	 */
	public RetryingPoolFetcher(CloudPoolDriver cloudDriver,
			RetriesConfig retriesConfig) {
		this(cloudDriver, retriesConfig.getMaxRetries(),
				retriesConfig.getInitialBackoffDelay());
	}

	@Override
	public void close() {
		// nothing to be done
	}

	/**
	 * Creates a {@link RetryingPoolFetcher} that will fetch machine pool
	 * members with the given {@link CloudPoolDriver}.
	 *
	 * @param cloudDriver
	 *            A cloud-specific management driver for the cloud pool.
	 * @param maxRetries
	 *            Maximum number of retries to make on failed attempts to fetch
	 *            pool members.
	 * @param initialBackoffDelay
	 *            Initial delay to use in exponential back-off on retries.
	 */
	public RetryingPoolFetcher(CloudPoolDriver cloudDriver, int maxRetries,
			TimeInterval initialBackoffDelay) {
		this.cloudDriver = cloudDriver;
		this.maxRetries = maxRetries;
		this.initialBackoffDelay = initialBackoffDelay;
	}

	@Override
	public MachinePool get(FetchOption... options) throws CloudPoolException {
		List machines = listMachines();
		MachinePool pool = new MachinePool(machines, UtcTime.now());
		return pool;
	}

	/**
	 * Lists the {@link Machine}s using the {@link CloudPoolDriver}.
	 *
	 * @return
	 */
	private List listMachines() throws CloudPoolException {
		int backoffDelay = this.initialBackoffDelay.getTime().intValue();
		TimeUnit backoffDelayUnit = this.initialBackoffDelay.getUnit();
		int maxAttempts = 1 + this.maxRetries;
		Retryable> retryable = Retryers.exponentialBackoffRetryer(
				"pool-fetch", new GetMachinePool(this.cloudDriver),
				backoffDelay, backoffDelayUnit, maxAttempts);
		try {
			return retryable.call();
		} catch (Exception e) {
			throw new CloudPoolException(
					String.format("gave up trying to fetch pool members: %s",
							e.getMessage()),
					e);
		}
	}

	private static class GetMachinePool implements Callable> {
		private final CloudPoolDriver cloudDriver;

		public GetMachinePool(CloudPoolDriver cloudDriver) {
			this.cloudDriver = cloudDriver;
		}

		@Override
		public List call() throws Exception {
			return this.cloudDriver.listMachines();
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy