diff --git a/compute/src/main/java/org/jclouds/compute/config/ComputeServiceProperties.java b/compute/src/main/java/org/jclouds/compute/config/ComputeServiceProperties.java index b071aacb04..640515f537 100644 --- a/compute/src/main/java/org/jclouds/compute/config/ComputeServiceProperties.java +++ b/compute/src/main/java/org/jclouds/compute/config/ComputeServiceProperties.java @@ -40,6 +40,12 @@ public interface ComputeServiceProperties { public static final String INIT_STATUS_INITIAL_PERIOD = "jclouds.compute.init-status.initial-period"; public static final String INIT_STATUS_MAX_PERIOD = "jclouds.compute.init-status.max-period"; + // The period in milliseconds between node updates when using the ComputeService + public static final String POLL_INITIAL_PERIOD = "jclouds.compute.poll-status.initial-period"; + + // The max period in milliseconds between node updates when using the ComputeService + public static final String POLL_MAX_PERIOD = "jclouds.compute.poll-status.max-period"; + /** * time in milliseconds to wait for an image to finish creating. * diff --git a/compute/src/main/java/org/jclouds/compute/config/ComputeServiceTimeoutsModule.java b/compute/src/main/java/org/jclouds/compute/config/ComputeServiceTimeoutsModule.java index adb01e7ad8..fcf180fb21 100644 --- a/compute/src/main/java/org/jclouds/compute/config/ComputeServiceTimeoutsModule.java +++ b/compute/src/main/java/org/jclouds/compute/config/ComputeServiceTimeoutsModule.java @@ -39,6 +39,7 @@ import org.jclouds.compute.predicates.AtomicNodeSuspended; import org.jclouds.compute.predicates.AtomicNodeTerminated; import org.jclouds.compute.predicates.ScriptStatusReturnsZero; import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient; +import org.jclouds.compute.reference.ComputeServiceConstants.PollPeriod; import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts; import org.jclouds.predicates.RetryablePredicate; @@ -56,26 +57,35 @@ public class ComputeServiceTimeoutsModule extends AbstractModule { @Provides @Singleton @Named(TIMEOUT_NODE_RUNNING) - protected Predicate> nodeRunning(AtomicNodeRunning statusRunning, Timeouts timeouts) { - return timeouts.nodeRunning == 0 ? statusRunning : new RetryablePredicateGuardingNull(statusRunning, - timeouts.nodeRunning); + protected Predicate> nodeRunning( + AtomicNodeRunning statusRunning, Timeouts timeouts, PollPeriod period) { + return timeouts.nodeRunning == 0 ? + statusRunning : + new RetryablePredicateGuardingNull( + statusRunning, timeouts.nodeRunning, period.pollInitialPeriod, period.pollMaxPeriod); } @Provides @Singleton @Named(TIMEOUT_NODE_TERMINATED) - protected Predicate> serverTerminated(AtomicNodeTerminated statusTerminated, Timeouts timeouts) { - return timeouts.nodeTerminated == 0 ? statusTerminated : new RetryablePredicate>(statusTerminated, - timeouts.nodeTerminated); + protected Predicate> serverTerminated( + AtomicNodeTerminated statusTerminated, Timeouts timeouts, PollPeriod period) { + return timeouts.nodeTerminated == 0 ? + statusTerminated : + new RetryablePredicate>( + statusTerminated, timeouts.nodeTerminated, period.pollInitialPeriod, period.pollMaxPeriod); } @Provides @Singleton @Named(TIMEOUT_NODE_SUSPENDED) - protected Predicate> serverSuspended(AtomicNodeSuspended statusSuspended, Timeouts timeouts) { - return timeouts.nodeSuspended == 0 ? statusSuspended : new RetryablePredicateGuardingNull(statusSuspended, - timeouts.nodeSuspended); + protected Predicate> serverSuspended( + AtomicNodeSuspended statusSuspended, Timeouts timeouts, PollPeriod period) { + return timeouts.nodeSuspended == 0 ? + statusSuspended : + new RetryablePredicateGuardingNull( + statusSuspended, timeouts.nodeSuspended, period.pollInitialPeriod, period.pollMaxPeriod); } @Provides @@ -89,17 +99,23 @@ public class ComputeServiceTimeoutsModule extends AbstractModule { @Provides @Singleton @Named(TIMEOUT_IMAGE_AVAILABLE) - protected Predicate> imageAvailable(AtomicImageAvailable statusAvailable, Timeouts timeouts) { - return timeouts.imageAvailable == 0 ? statusAvailable : new RetryablePredicateGuardingNull(statusAvailable, - timeouts.imageAvailable); + protected Predicate> imageAvailable( + AtomicImageAvailable statusAvailable, Timeouts timeouts, PollPeriod period) { + return timeouts.imageAvailable == 0 ? + statusAvailable : + new RetryablePredicateGuardingNull( + statusAvailable, timeouts.imageAvailable, period.pollInitialPeriod, period.pollMaxPeriod); } @Provides @Singleton @Named(TIMEOUT_IMAGE_DELETED) - protected Predicate> serverDeleted(AtomicImageDeleted statusDeleted, Timeouts timeouts) { - return timeouts.imageDeleted == 0 ? statusDeleted : new RetryablePredicate>(statusDeleted, - timeouts.imageDeleted); + protected Predicate> serverDeleted( + AtomicImageDeleted statusDeleted, Timeouts timeouts, PollPeriod period) { + return timeouts.imageDeleted == 0 ? + statusDeleted : + new RetryablePredicate>( + statusDeleted, timeouts.imageDeleted, period.pollInitialPeriod, period.pollMaxPeriod); } @Override @@ -127,7 +143,7 @@ public class ComputeServiceTimeoutsModule extends AbstractModule { private final RetryablePredicate retryablePredicate; - public RetryablePredicateGuardingNull(final Predicate> predicate, long maxWait) { + public RetryablePredicateGuardingNull(final Predicate> predicate, long maxWait, long period, long maxPeriod) { Predicate nonNullThingPredicate = new Predicate() { @Override public boolean apply(AtomicRefAndOrig input) { @@ -139,7 +155,7 @@ public class ComputeServiceTimeoutsModule extends AbstractModule { } } }; - retryablePredicate = new RetryablePredicate(nonNullThingPredicate, maxWait); + retryablePredicate = new RetryablePredicate(nonNullThingPredicate, maxWait, period, maxPeriod); } @Override diff --git a/compute/src/main/java/org/jclouds/compute/reference/ComputeServiceConstants.java b/compute/src/main/java/org/jclouds/compute/reference/ComputeServiceConstants.java index ba39b1f700..6cefff9a91 100644 --- a/compute/src/main/java/org/jclouds/compute/reference/ComputeServiceConstants.java +++ b/compute/src/main/java/org/jclouds/compute/reference/ComputeServiceConstants.java @@ -24,6 +24,8 @@ import static org.jclouds.compute.config.ComputeServiceProperties.IMAGE_ID; import static org.jclouds.compute.config.ComputeServiceProperties.IMAGE_LOGIN_USER; import static org.jclouds.compute.config.ComputeServiceProperties.INIT_STATUS_INITIAL_PERIOD; import static org.jclouds.compute.config.ComputeServiceProperties.INIT_STATUS_MAX_PERIOD; +import static org.jclouds.compute.config.ComputeServiceProperties.POLL_INITIAL_PERIOD; +import static org.jclouds.compute.config.ComputeServiceProperties.POLL_MAX_PERIOD; import static org.jclouds.compute.config.ComputeServiceProperties.OS_VERSION_MAP_JSON; import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE; import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_DELETED; @@ -40,6 +42,7 @@ import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.compute.config.ComputeServiceProperties; +import org.jclouds.predicates.RetryablePredicate; import com.google.common.base.Supplier; import com.google.inject.Inject; @@ -52,7 +55,7 @@ public interface ComputeServiceConstants { public static final String COMPUTE_LOGGER = "jclouds.compute"; public static final String LOCAL_PARTITION_GB_PATTERN = "disk_drive/%s/gb"; - + /** * @see ComputeServiceProperties#TIMEOUT_NODE_TERMINATED */ @@ -139,6 +142,17 @@ public interface ComputeServiceConstants { public long initStatusMaxPeriod = 5000; } + @Singleton + public static class PollPeriod { + @Inject(optional = true) + @Named(POLL_INITIAL_PERIOD) + public long pollInitialPeriod = RetryablePredicate.DEFAULT_PERIOD; + + @Inject(optional = true) + @Named(POLL_MAX_PERIOD) + public long pollMaxPeriod = RetryablePredicate.DEFAULT_MAX_PERIOD; + } + @Singleton public static class ReferenceData { @Inject(optional = true) diff --git a/compute/src/test/java/org/jclouds/compute/config/ComputeServicePropertiesTest.java b/compute/src/test/java/org/jclouds/compute/config/ComputeServicePropertiesTest.java index 573d333351..4e28610033 100644 --- a/compute/src/test/java/org/jclouds/compute/config/ComputeServicePropertiesTest.java +++ b/compute/src/test/java/org/jclouds/compute/config/ComputeServicePropertiesTest.java @@ -24,6 +24,7 @@ import java.util.Properties; import org.jclouds.ContextBuilder; import org.jclouds.compute.reference.ComputeServiceConstants.InitStatusProperties; +import org.jclouds.compute.reference.ComputeServiceConstants.PollPeriod; import org.testng.annotations.Test; /** @@ -51,4 +52,22 @@ public class ComputeServicePropertiesTest { assertEquals(props.initStatusMaxPeriod, 5001); } + public void testDefaultPollPeriod() { + PollPeriod props = ContextBuilder.newBuilder("stub").buildInjector() + .getInstance(PollPeriod.class); + assertEquals(props.pollInitialPeriod, 50); + assertEquals(props.pollMaxPeriod, 1000); + } + + public void testOverridePollPeriod() { + Properties overrides = new Properties(); + overrides.setProperty(ComputeServiceProperties.POLL_INITIAL_PERIOD, "501"); + overrides.setProperty(ComputeServiceProperties.POLL_MAX_PERIOD, "5001"); + + PollPeriod props = ContextBuilder.newBuilder("stub").overrides(overrides).buildInjector() + .getInstance(PollPeriod.class); + + assertEquals(props.pollInitialPeriod, 501); + assertEquals(props.pollMaxPeriod, 5001); + } } diff --git a/compute/src/test/java/org/jclouds/compute/strategy/CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapTest.java b/compute/src/test/java/org/jclouds/compute/strategy/CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapTest.java index 0634637263..2226034ac1 100644 --- a/compute/src/test/java/org/jclouds/compute/strategy/CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapTest.java +++ b/compute/src/test/java/org/jclouds/compute/strategy/CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapTest.java @@ -41,6 +41,7 @@ import org.jclouds.compute.domain.NodeMetadataBuilder; import org.jclouds.compute.functions.TemplateOptionsToStatement; import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.predicates.AtomicNodeRunning; +import org.jclouds.compute.reference.ComputeServiceConstants.PollPeriod; import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts; import org.jclouds.compute.util.OpenSocketFinder; import org.jclouds.scriptbuilder.domain.Statement; @@ -202,6 +203,7 @@ public class CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapTest { InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory = createMock(InitializeRunScriptOnNodeOrPlaceInBadMap.Factory.class); OpenSocketFinder openSocketFinder = createMock(OpenSocketFinder.class); Timeouts timeouts = new Timeouts(); + PollPeriod period = new PollPeriod(); Function templateOptionsToStatement = new TemplateOptionsToStatement(); Set goodNodes = Sets.newLinkedHashSet(); Map badNodes = Maps.newLinkedHashMap(); @@ -213,10 +215,10 @@ public class CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapTest { GetNodeMetadataStrategy nodeClient = createMock(GetNodeMetadataStrategy.class); AtomicNodeRunning nodeRunning = new AtomicNodeRunning(nodeClient); Predicate> retryableNodeRunning = new ComputeServiceTimeoutsModule() { - public Predicate> nodeRunning(AtomicNodeRunning statusRunning, Timeouts timeouts) { - return super.nodeRunning(statusRunning, timeouts); + public Predicate> nodeRunning(AtomicNodeRunning statusRunning, Timeouts timeouts, PollPeriod period) { + return super.nodeRunning(statusRunning, timeouts, period); } - }.nodeRunning(nodeRunning, timeouts); + }.nodeRunning(nodeRunning, timeouts, period); AtomicReference atomicNode = new AtomicReference(pendingNode); // Simulate transient error: first call returns null; subsequent calls return the running node diff --git a/core/src/main/java/org/jclouds/predicates/RetryablePredicate.java b/core/src/main/java/org/jclouds/predicates/RetryablePredicate.java index 79d142b1ef..d607589c76 100644 --- a/core/src/main/java/org/jclouds/predicates/RetryablePredicate.java +++ b/core/src/main/java/org/jclouds/predicates/RetryablePredicate.java @@ -44,6 +44,9 @@ import com.google.common.base.Predicate; * @author Adrian Cole */ public class RetryablePredicate implements Predicate { + public static final long DEFAULT_PERIOD = 50l; + public static final long DEFAULT_MAX_PERIOD = 1000l; + private final long maxWait; private final long period; private final long maxPeriod; @@ -63,8 +66,12 @@ public class RetryablePredicate implements Predicate { this(predicate, maxWait, period, period * 10l, unit); } + public RetryablePredicate(Predicate predicate, long maxWait, long period, long maxPeriod) { + this(predicate, maxWait, period, maxPeriod, TimeUnit.MILLISECONDS); + } + public RetryablePredicate(Predicate predicate, long maxWait) { - this(predicate, maxWait, 50l, 1000l, TimeUnit.MILLISECONDS); + this(predicate, maxWait, DEFAULT_PERIOD, DEFAULT_MAX_PERIOD, TimeUnit.MILLISECONDS); } @Override