Java Code Examples for org.apache.brooklyn.util.time.Time#sleep()

The following examples show how to use org.apache.brooklyn.util.time.Time#sleep() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ServiceFailureDetectorTest.java    From brooklyn-server with Apache License 2.0 6 votes vote down vote up
@Test(groups="Integration") // Has a 1 second wait
public void testOnFireAfterDelay() throws Exception {
    e1.enrichers().add(EnricherSpec.create(ServiceFailureDetector.class)
        .configure(ServiceFailureDetector.SERVICE_ON_FIRE_STABILIZATION_DELAY, Duration.ONE_SECOND));
    
    // Make the entity fail
    e1.sensors().set(TestEntity.SERVICE_UP, true);
    ServiceStateLogic.setExpectedState(e1, Lifecycle.RUNNING);
    EntityAsserts.assertAttributeEqualsEventually(e1, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
    
    e1.sensors().set(TestEntity.SERVICE_UP, false);

    assertEquals(e1.getAttribute(TestEntity.SERVICE_STATE_ACTUAL), Lifecycle.RUNNING);
    Time.sleep(Duration.millis(100));
    assertEquals(e1.getAttribute(TestEntity.SERVICE_STATE_ACTUAL), Lifecycle.RUNNING);
    EntityAsserts.assertAttributeEqualsEventually(e1, TestEntity.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
}
 
Example 2
Source File: RiakClusterImpl.java    From brooklyn-library with Apache License 2.0 6 votes vote down vote up
@Override
protected void doStart() {
    super.doStart();
    connectSensors();

    try {
        Duration delay = getConfig(DELAY_BEFORE_ADVERTISING_CLUSTER);
        Tasks.setBlockingDetails("Sleeping for "+delay+" before advertising cluster available");
        Time.sleep(delay);
    } finally {
        Tasks.resetBlockingDetails();
    }

    //FIXME: add a quorum to tolerate failed nodes before setting on fire.
    @SuppressWarnings("unchecked")
    Optional<Entity> anyNode = Iterables.tryFind(getMembers(), Predicates.and(
            Predicates.instanceOf(RiakNode.class),
            EntityPredicates.attributeEqualTo(RiakNode.RIAK_NODE_HAS_JOINED_CLUSTER, true),
            EntityPredicates.attributeEqualTo(RiakNode.SERVICE_UP, true)));
    if (anyNode.isPresent()) {
        sensors().set(IS_CLUSTER_INIT, true);
    } else {
        log.warn("No Riak Nodes are found on the cluster: {}. Initialization Failed", getId());
        ServiceStateLogic.setExpectedState(this, Lifecycle.ON_FIRE);
    }
}
 
Example 3
Source File: ShellToolAbstractTest.java    From brooklyn-server with Apache License 2.0 6 votes vote down vote up
protected void runExecBigConcurrentCommand(int numCommands, long staggeredDelayBeforeStart) throws Exception {
    ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
    List<ListenableFuture<?>> futures = new ArrayList<ListenableFuture<?>>();
    try {
        for (int i = 0; i < numCommands; i++) {
            long delay = (long) (Math.random() * staggeredDelayBeforeStart);
            if (i > 0) Time.sleep(delay);
            
            futures.add(executor.submit(new Runnable() {
                    @Override
                    public void run() {
                        String bigstring = Strings.repeat("abcdefghij", 1000); // 10KB
                        String out = execCommands("echo "+bigstring);
                        assertEquals(out, bigstring+"\n", "actualSize="+out.length()+"; expectedSize="+bigstring.length());
                    }}));
        }
        Futures.allAsList(futures).get();
    } finally {
        executor.shutdownNow();
    }
}
 
Example 4
Source File: CassandraDatacenterLiveTest.java    From brooklyn-library with Apache License 2.0 6 votes vote down vote up
protected static void checkConnectionRepeatedly(int totalAttemptsAllowed, int numRetriesPerAttempt, Iterable<? extends Entity> nodes) throws Exception {
    int attemptNum = 0;
    while (true) {
        try {
            checkConnection(numRetriesPerAttempt, nodes);
            return;
        } catch (Exception e) {
            attemptNum++;
            if (attemptNum >= totalAttemptsAllowed) {
                log.warn("Cassandra not usable, "+attemptNum+" attempts; failing: "+e, e);
                throw e;                
            }
            log.warn("Cassandra not usable (attempt "+attemptNum+" of "+totalAttemptsAllowed+"), trying again after delay: "+e, e);
            Time.sleep(Duration.TEN_SECONDS);
        }
    }
}
 
Example 5
Source File: HotStandbyTest.java    From brooklyn-server with Apache License 2.0 5 votes vote down vote up
public void assertUsedMemoryLessThan(String event, long max) {
    noteUsedMemory(event);
    long nowUsed = usedMemory.peekLast();
    if (nowUsed > max) {
        // aggressively try to force GC
        Time.sleep(Duration.ONE_SECOND);
        usedMemory.removeLast();
        noteUsedMemory(event+" (extra GC)");
        nowUsed = usedMemory.peekLast();
        if (nowUsed > max) {
            Assert.fail("Too much memory used - "+ByteSizeStrings.java().apply(nowUsed)+" > max "+ByteSizeStrings.java().apply(max));
        }
    }
}
 
Example 6
Source File: Tasks.java    From brooklyn-server with Apache License 2.0 5 votes vote down vote up
/** 
 * Workaround for limitation described at {@link Task#cancel(boolean)};
 * internal method used to allow callers to wait for underlying tasks to finished in the case of cancellation.
 * <p> 
 * It is irritating that {@link FutureTask} sync's object clears the runner thread, 
 * so even if {@link BasicTask#getInternalFuture()} is used, there is no means of determining if the underlying object is done.
 * The {@link Task#getEndTimeUtc()} seems the only way.
 *  
 * @return true if tasks ended; false if timed out
 **/ 
@Beta
public static boolean blockUntilInternalTasksEnded(Task<?> t, Duration timeout) {
    CountdownTimer timer = timeout.countdownTimer();
    
    if (t==null)
        return true;
    
    if (t instanceof ScheduledTask) {
        boolean result = ((ScheduledTask)t).blockUntilNextRunFinished(timer.getDurationRemaining());
        if (!result) return false;
    }

    t.blockUntilEnded(timer.getDurationRemaining());
    
    while (true) {
        if (t.getEndTimeUtc()>=0) return true;
        // above should be sufficient; but just in case, trying the below
        Thread tt = t.getThread();
        if (t instanceof ScheduledTask) {
            ((ScheduledTask)t).blockUntilNextRunFinished(timer.getDurationRemaining());
            return true;
        } else {
            if (tt==null || !tt.isAlive()) {
                if (!t.isCancelled()) {
                    // may happen for a cancelled task, interrupted after submit but before start
                    log.warn("Internal task thread is dead or null ("+tt+") but task not ended: "+t.getEndTimeUtc()+" ("+t+")");
                }
                return true;
            }
        }
        if (timer.isExpired())
            return false;
        Time.sleep(Repeater.DEFAULT_REAL_QUICK_PERIOD);
    }
}
 
Example 7
Source File: ChefServerTasksIntegrationTest.java    From brooklyn-library with Apache License 2.0 5 votes vote down vote up
@Test(groups="Integration")
@SuppressWarnings("resource")
public void testWhichKnife() throws IOException, InterruptedException {
    // requires that knife is installed on the path of login shells
    Process p = Runtime.getRuntime().exec(new String[] { "bash", "-l", "-c", "which knife" });
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    new StreamGobbler(p.getInputStream(), out, log).start();
    new StreamGobbler(p.getErrorStream(), out, log).start();
    log.info("bash -l -c 'which knife' gives exit code: "+p.waitFor());
    Time.sleep(Duration.millis(1000));
    log.info("output:\n"+out);
    Assert.assertEquals(p.exitValue(), 0);
}
 
Example 8
Source File: CompoundTaskExecutionTest.java    From brooklyn-server with Apache License 2.0 5 votes vote down vote up
private BasicTask<String> slowTaskReturning(final String val, final Duration pauseTime) {
    return new BasicTask<String>(new Callable<String>() {
            @Override public String call() {
                Time.sleep(pauseTime);
                return val;
            }
        });
}
 
Example 9
Source File: ChefLifecycleEffectorTasks.java    From brooklyn-library with Apache License 2.0 5 votes vote down vote up
protected boolean tryCheckStartWindowsService() {
    if (getWindowsServiceName()==null) return false;
    
    // if it's still up after 5s assume we are good (default behaviour)
    Time.sleep(Duration.FIVE_SECONDS);
    if (!((Integer)0).equals(DynamicTasks.queue(SshEffectorTasks.ssh("sc query \""+getWindowsServiceName()+"\" | find \"RUNNING\"").runAsCommand()).get())) {
        throw new IllegalStateException("The process for "+entity()+" appears not to be running (windowsService "+getWindowsServiceName()+")");
    }

    return true;
}
 
Example 10
Source File: ReachableSocketFinderTest.java    From brooklyn-server with Apache License 2.0 5 votes vote down vote up
@Test
public void testSocketResultIgnoredIfGracePeriodExpiresAfterFirstResultAvailable() {
    reachabilityResults.put(socket1, false);
    reachabilityResults.put(socket2, true);
    // Override the default test grace period.
    finder = new ReachableSocketFinder(socketTester, Duration.ZERO);
    final Iterable<HostAndPort> actual = finder.findOpenSocketsOnNode(ImmutableList.of(socket1, socket2), TIMEOUT);
    // Sleep through the grace period.
    Time.sleep(50);
    reachabilityResults.put(socket1, true);
    assertEquals(actual, ImmutableList.of(socket2));
}
 
Example 11
Source File: InterruptingImmediateSupplierTest.java    From brooklyn-server with Apache License 2.0 4 votes vote down vote up
@Override public void run() {
    Time.sleep(Duration.ONE_MINUTE);
}
 
Example 12
Source File: JcloudsLocationReleasePortForwardingDefaultTest.java    From brooklyn-server with Apache License 2.0 4 votes vote down vote up
@Override
public void closePortForwarding(NodeMetadata node, int targetPort, HostAndPort publicHostAndPort, Protocol protocol) {
    calls.add(ImmutableList.of("close", System.currentTimeMillis(), node, targetPort, publicHostAndPort, protocol));
    Time.sleep(sleepBeforeReturning);
}
 
Example 13
Source File: InterruptingImmediateSupplierTest.java    From brooklyn-server with Apache License 2.0 4 votes vote down vote up
@Override public Void call() {
    Time.sleep(Duration.ONE_MINUTE);
    return null;
}
 
Example 14
Source File: RebindFeedTest.java    From brooklyn-server with Apache License 2.0 4 votes vote down vote up
public void doReReReRebindDedupesCorrectlyBasedOnTagOrContentsPersisted(int datasize, int iterations, boolean soakTest) throws Exception {
    final int SYSTEM_TASK_COUNT = 2;  // normally 1, persistence; but as long as less than 4 (the original) we're fine
    final int MAX_ALLOWED_LEAK = 50*1000*1000;  // memory can vary wildly; but our test should eventually hit GB if there's a leak so this is fine
    
    TestEntity origEntity = origApp.createAndManageChild(EntitySpec.create(TestEntity.class).impl(MyEntityWithNewFeedsEachTimeImpl.class)
        .configure(MyEntityWithNewFeedsEachTimeImpl.DATA_SIZE, datasize)
        .configure(MyEntityWithNewFeedsEachTimeImpl.MAKE_NEW, true));
    origApp.start(ImmutableList.<Location>of());

    List<Feed> knownFeeds = MutableList.of();
    TestEntity currentEntity = origEntity;
    Collection<Feed> currentFeeds = currentEntity.feeds().getFeeds();
    
    int expectedCount = 4;
    assertEquals(currentFeeds.size(), expectedCount);
    knownFeeds.addAll(currentFeeds);
    assertActiveFeedsEventually(knownFeeds, expectedCount);
    origEntity.config().set(MyEntityWithNewFeedsEachTimeImpl.MAKE_NEW, !soakTest);
    
    long usedOriginally = -1;
    
    for (int i=0; i<iterations; i++) {
        log.info("rebinding, iteration "+i);
        newApp = rebind();
        
        // should get 2 new ones
        if (!soakTest) expectedCount += 2;
        
        currentEntity = (TestEntity) Iterables.getOnlyElement(newApp.getChildren());
        currentFeeds = currentEntity.feeds().getFeeds();
        assertEquals(currentFeeds.size(), expectedCount, "feeds are: "+currentFeeds);
        knownFeeds.addAll(currentFeeds);

        switchOriginalToNewManagementContext();
        waitForTaskCountToBecome(origManagementContext, expectedCount + SYSTEM_TASK_COUNT);
        assertActiveFeedsEventually(knownFeeds, expectedCount);
        knownFeeds.clear();
        knownFeeds.addAll(currentFeeds);
        
        if (soakTest) {
            System.gc(); System.gc();
            if (usedOriginally<0) {
                Time.sleep(Duration.millis(200));  // give things time to settle; means this number should be larger than others, if anything
                usedOriginally = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
                log.info("Usage after first rebind: "+BrooklynGarbageCollector.makeBasicUsageString()+" ("+Strings.makeJavaSizeString(usedOriginally)+")");
            } else {
                long usedNow = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
                log.info("Usage: "+BrooklynGarbageCollector.makeBasicUsageString()+" ("+Strings.makeJavaSizeString(usedNow)+")");
                Assert.assertFalse(usedNow-usedOriginally > MAX_ALLOWED_LEAK, "Leaked too much memory: "+Strings.makeJavaSizeString(usedNow)+" now used, was "+Strings.makeJavaSizeString(usedOriginally));
            }
        }
    }
}
 
Example 15
Source File: InterruptingImmediateSupplierTest.java    From brooklyn-server with Apache License 2.0 4 votes vote down vote up
@Override public Void get() {
    Time.sleep(Duration.ONE_MINUTE);
    return null;
}
 
Example 16
Source File: HttpAssertsTest.java    From brooklyn-server with Apache License 2.0 4 votes vote down vote up
@AfterMethod(alwaysRun = true)
public void tearDown() throws Exception {
    if (executor != null) executor.shutdownNow();
    server.stop();
    Time.sleep(DELAY_FOR_SERVER_TO_SETTLE);
}
 
Example 17
Source File: EntityExecutionManagerTest.java    From brooklyn-server with Apache License 2.0 4 votes vote down vote up
public void testGcTaskWithTagAndEntityLimit() throws Exception {
    TestEntity e = app.createAndManageChild(EntitySpec.create(TestEntity.class));
    
    ((BrooklynProperties)app.getManagementContext().getConfig()).put(
        BrooklynGarbageCollector.MAX_TASKS_PER_ENTITY, 6);
    ((BrooklynProperties)app.getManagementContext().getConfig()).put(
        BrooklynGarbageCollector.MAX_TASKS_PER_TAG, 2);

    AtomicBoolean stopCondition = new AtomicBoolean();
    scheduleRecursiveTemporaryTask(stopCondition, e, "boring-tag");
    scheduleRecursiveTemporaryTask(stopCondition, e, "boring-tag");
    scheduleRecursiveTemporaryTask(stopCondition, app, "boring-tag");
    scheduleRecursiveTemporaryTask(stopCondition, app, "boring-tag");

    int count=0;
    
    runEmptyTaskWithNameAndTags(app, "task-"+(count++), ManagementContextInternal.NON_TRANSIENT_TASK_TAG, "boring-tag");
    runEmptyTaskWithNameAndTags(e, "task-"+(count++), ManagementContextInternal.NON_TRANSIENT_TASK_TAG, "boring-tag");
    Time.sleep(Duration.ONE_MILLISECOND);
    // should keep the 2 below, because all the other borings get grace, but delete the ones above
    runEmptyTaskWithNameAndTags(e, "task-"+(count++), ManagementContextInternal.NON_TRANSIENT_TASK_TAG, "boring-tag");
    runEmptyTaskWithNameAndTags(e, "task-"+(count++), ManagementContextInternal.NON_TRANSIENT_TASK_TAG, "boring-tag");
    
    runEmptyTaskWithNameAndTags(e, "task-"+(count++), ManagementContextInternal.NON_TRANSIENT_TASK_TAG, "boring-tag", "another-tag-e");
    runEmptyTaskWithNameAndTags(e, "task-"+(count++), ManagementContextInternal.NON_TRANSIENT_TASK_TAG, "boring-tag", "another-tag-e");
    // should keep both the above
    
    runEmptyTaskWithNameAndTags(e, "task-"+(count++), ManagementContextInternal.NON_TRANSIENT_TASK_TAG, "another-tag");
    runEmptyTaskWithNameAndTags(e, "task-"+(count++), ManagementContextInternal.NON_TRANSIENT_TASK_TAG, "another-tag");
    Time.sleep(Duration.ONE_MILLISECOND);
    runEmptyTaskWithNameAndTags(app, "task-"+(count++), ManagementContextInternal.NON_TRANSIENT_TASK_TAG, "another-tag");
    // should keep the below since they have unique tags, but remove one of the e tasks above 
    runEmptyTaskWithNameAndTags(e, "task-"+(count++), ManagementContextInternal.NON_TRANSIENT_TASK_TAG, "another-tag", "and-another-tag");
    runEmptyTaskWithNameAndTags(app, "task-"+(count++), ManagementContextInternal.NON_TRANSIENT_TASK_TAG, "another-tag-app", "another-tag");
    runEmptyTaskWithNameAndTags(app, "task-"+(count++), ManagementContextInternal.NON_TRANSIENT_TASK_TAG, "another-tag-app", "another-tag");
    
    // Makes sure there's a GC while the transient tasks are running
    forceGc();
    stopCondition.set(true);

    assertTaskMaxCountForEntityEventually(e, 6);
    assertTaskMaxCountForEntityEventually(app, 3);
    
    // now with a lowered limit, we should remove one more e
    ((BrooklynProperties)app.getManagementContext().getConfig()).put(
        BrooklynGarbageCollector.MAX_TASKS_PER_ENTITY, 5);
    assertTaskMaxCountForEntityEventually(e, 5);
}
 
Example 18
Source File: HttpAssertsTest.java    From brooklyn-server with Apache License 2.0 4 votes vote down vote up
@BeforeMethod(alwaysRun = true)
public void setUp() throws Exception {
    server = initializeServer();
    initVars();
    Time.sleep(DELAY_FOR_SERVER_TO_SETTLE);
}
 
Example 19
Source File: OpenShiftEntityImpl.java    From SeaCloudsPlatform with Apache License 2.0 4 votes vote down vote up
/**
 * Copied direcly from {@link brooklyn.entity.basic.SoftwareProcessImpl}
 */
// TODO Find a better way to detect early death of process.
public void waitForEntityStart() {
    if (log.isDebugEnabled()) {
        log.debug("waiting to ensure {} doesn't abort prematurely", this);
    }
    Duration startTimeout = getConfig(START_TIMEOUT);
    CountdownTimer timer = startTimeout.countdownTimer();
    boolean isRunningResult = false;
    long delay = 100;
    while (!isRunningResult && !timer.isExpired()) {
        Time.sleep(delay);
        try {
            isRunningResult = driver.isRunning();
        } catch (Exception e) {
            ServiceStateLogic.setExpectedState(this, Lifecycle.ON_FIRE);
            // provide extra context info, as we're seeing this happen in strange circumstances
            if (driver == null) {
                throw new IllegalStateException(this +
                        " concurrent start and shutdown detected");
            }
            throw new IllegalStateException("Error detecting whether " + this +
                    " is running: " + e, e);
        }
        if (log.isDebugEnabled()) {
            log.debug("checked {}, is running returned: {}", this, isRunningResult);
        }
        // slow exponential delay -- 1.1^N means after 40 tries and 50s elapsed, it reaches
        // the max of 5s intervals
        // TODO use Repeater
        delay = Math.min(delay * 11 / 10, 5000);
    }
    if (!isRunningResult) {
        String msg = "Software process entity " + this + " did not pass is-running " +
                "check within the required " + startTimeout + " limit (" +
                timer.getDurationElapsed().toStringRounded() + " elapsed)";
        log.warn(msg + " (throwing)");
        ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING);
        throw new IllegalStateException(msg);
    }
}
 
Example 20
Source File: CassandraNodeSshDriver.java    From brooklyn-library with Apache License 2.0 4 votes vote down vote up
@Override
public void launch() {
    String subnetHostname = Machines.findSubnetOrPublicHostname(entity).get();
    Set<Entity> seeds = getEntity().getConfig(CassandraNode.INITIAL_SEEDS);
    List<Entity> ancestors = getCassandraAncestors();
    log.info("Launching " + entity + ": " +
            "cluster "+getClusterName()+", " +
            "hostname (public) " + getEntity().getAttribute(Attributes.HOSTNAME) + ", " +
            "hostname (subnet) " + subnetHostname + ", " +
            "seeds "+((CassandraNode)entity).getSeeds()+" (from "+seeds+")");

    boolean isFirst = seeds.iterator().next().equals(entity);
    if (isClustered() && !isFirst && CassandraDatacenter.WAIT_FOR_FIRST) {
        // wait for the first node
        long firstStartTime = Entities.submit(entity, DependentConfiguration.attributeWhenReady(
            ancestors.get(ancestors.size()-1), CassandraDatacenter.FIRST_NODE_STARTED_TIME_UTC)).getUnchecked();
        // optionally force a delay before starting subsequent nodes; see comment at CassandraCluster.DELAY_AFTER_FIRST
        Duration toWait = Duration.millis(firstStartTime + CassandraDatacenter.DELAY_AFTER_FIRST.toMilliseconds() -  System.currentTimeMillis());
        if (toWait.toMilliseconds()>0) {
            log.info("Launching " + entity + ": delaying launch of non-first node by "+toWait+" to prevent schema disagreements");
            Tasks.setBlockingDetails("Pausing to ensure first node has time to start");
            Time.sleep(toWait);
            Tasks.resetBlockingDetails();
        }
    }

    List<Entity> queuedStart = null;
    if (CassandraDatacenter.DELAY_BETWEEN_STARTS!=null && !ancestors.isEmpty()) {
        Entity root = ancestors.get(ancestors.size()-1);
        // TODO currently use the class as a semaphore; messy, and obviously will not federate;
        // should develop a brooklyn framework semaphore (similar to that done on SshMachineLocation)
        // and use it - note however the synch block is very very short so relatively safe at least
        synchronized (CassandraNode.class) {
            queuedStart = root.getAttribute(CassandraDatacenter.QUEUED_START_NODES);
            if (queuedStart==null) {
                queuedStart = new ArrayList<Entity>();
                root.sensors().set(CassandraDatacenter.QUEUED_START_NODES, queuedStart);
            }
            queuedStart.add(getEntity());
            root.sensors().set(CassandraDatacenter.QUEUED_START_NODES, queuedStart);
        }
        do {
            // get it again in case it is backed by something external
            queuedStart = root.getAttribute(CassandraDatacenter.QUEUED_START_NODES);
            if (queuedStart.get(0).equals(getEntity())) break;
            synchronized (queuedStart) {
                try {
                    queuedStart.wait(1000);
                } catch (InterruptedException e) {
                    Exceptions.propagate(e);
                }
            }
        } while (true);

        // TODO should look at last start time... but instead we always wait
        CassandraDatacenter.DELAY_BETWEEN_STARTS.countdownTimer().waitForExpiryUnchecked();
    }

    try {
        // Relies on `bin/cassandra -p <pidfile>`, rather than us writing pid file ourselves.
        newScript(MutableMap.of(USE_PID_FILE, false), LAUNCHING)
                .body.append(
                        // log the date to attempt to debug occasional http://wiki.apache.org/cassandra/FAQ#schema_disagreement
                        // (can be caused by machines out of synch time-wise; but in our case it seems to be caused by other things!)
                        "echo date on cassandra server `hostname` when launching is `date`",
                        launchEssentialCommand(),
                        "echo after essential command")
                .execute();
        if (!isClustered()) {
            InputStream creationScript = DatastoreMixins.getDatabaseCreationScript(entity);
            if (creationScript!=null) {
                Tasks.setBlockingDetails("Pausing to ensure Cassandra (singleton) has started before running creation script");
                Time.sleep(Duration.seconds(20));
                Tasks.resetBlockingDetails();
                executeScriptAsync(Streams.readFullyStringAndClose(creationScript));
            }
        }
        if (isClustered() && isFirst) {
            for (Entity ancestor: getCassandraAncestors()) {
                ancestor.sensors().set(CassandraDatacenter.FIRST_NODE_STARTED_TIME_UTC, System.currentTimeMillis());
            }
        }
    } finally {
        if (queuedStart!=null) {
            Entity head = queuedStart.remove(0);
            checkArgument(head.equals(getEntity()), "first queued node was "+head+" but we are "+getEntity());
            synchronized (queuedStart) {
                queuedStart.notifyAll();
            }
        }
    }
}