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

com.elastisys.scale.cloudpool.aws.commons.requests.ec2.CancelSpotInstanceRequests Maven / Gradle / Ivy

There is a newer version: 5.2.3
Show newest version
package com.elastisys.scale.cloudpool.aws.commons.requests.ec2;

import static com.amazonaws.services.ec2.model.SpotInstanceState.Cancelled;
import static com.elastisys.scale.cloudpool.aws.commons.predicates.SpotRequestPredicates.allInAnyOfStates;

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

import com.amazonaws.AmazonClientException;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.services.ec2.model.CancelSpotInstanceRequestsRequest;
import com.amazonaws.services.ec2.model.CancelSpotInstanceRequestsResult;
import com.amazonaws.services.ec2.model.SpotInstanceRequest;
import com.elastisys.scale.commons.net.retryable.Retryable;
import com.elastisys.scale.commons.net.retryable.Retryers;
import com.google.common.collect.ImmutableList;

/**
 * A {@link Callable} task that, when executed, requests a collection of spot
 * instance requests to be canceled in a region and waits for the requests to
 * appear cancelled in {@code DescribeSpotRequestInstances}, which may not be
 * immediate due to the eventual consistency semantics of the Amazon API.
 */
public class CancelSpotInstanceRequests
		extends AmazonEc2Request {
	/** Initial exponential back-off delay in ms. */
	private static final int INITIAL_BACKOFF_DELAY = 1000;
	/** Maximum number of retries of operations. */
	private static final int MAX_RETRIES = 8;

	/** The {@link SpotInstanceRequest} to cancel. */
	private final List spotRequestIds;

	public CancelSpotInstanceRequests(AWSCredentials awsCredentials,
			String region, ClientConfiguration clientConfig,
			List spotInstanceRequestIds) {
		super(awsCredentials, region, clientConfig);
		this.spotRequestIds = ImmutableList.copyOf(spotInstanceRequestIds);
	}

	@Override
	public CancelSpotInstanceRequestsResult call()
			throws AmazonClientException {
		CancelSpotInstanceRequestsRequest request = new CancelSpotInstanceRequestsRequest()
				.withSpotInstanceRequestIds(this.spotRequestIds);
		CancelSpotInstanceRequestsResult result = getClient().getApi()
				.cancelSpotInstanceRequests(request);
		awaitCancellation(this.spotRequestIds);
		return result;
	}

	/**
	 * Waits for the cancelled spot instance requests to be reported as
	 * cancelled by the Amazon API.
	 *
	 * @param spotRequestIds
	 */
	private void awaitCancellation(List spotRequestIds) {
		String name = String.format("await-cancelled{%s}", spotRequestIds);
		GetSpotInstanceRequests requester = new GetSpotInstanceRequests(
				getAwsCredentials(), getRegion(), getClientConfig(),
				spotRequestIds, null);
		Retryable> retryer = Retryers
				.exponentialBackoffRetryer(name, requester,
						INITIAL_BACKOFF_DELAY, TimeUnit.MILLISECONDS,
						MAX_RETRIES, allInAnyOfStates(Cancelled.toString()));

		try {
			retryer.call();
		} catch (Exception e) {
			throw new RuntimeException(String.format(
					"gave up waiting for spot instance requests "
							+ "to be cancelled %s: %s",
					spotRequestIds, e.getMessage()), e);
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy