Skip to content

Conversation

@Yavor16
Copy link
Contributor

@Yavor16 Yavor16 commented Jan 5, 2026

No description provided.

@Yavor16 Yavor16 force-pushed the application-shutdown-logic-update branch 2 times, most recently from 31b61f2 to 8da103c Compare January 5, 2026 09:25
instanceShutdownExecutor.execute(applicationGuid, i);
public void execute(String applicationId, int applicationInstanceCount) {
ApplicationShutdownScheduler applicationShutdownScheduler = getApplicationShutdownScheduler();
List<ApplicationShutdown> scheduledApplicationShutdowns = applicationShutdownScheduler.scheduleApplicationForShutdown(applicationId,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will happen if count of instances is mistaken or some of existing instances are in crashed/not running state? Will it lead to infinite loop?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i dont it will because if an instance has crashed on startup, the instance will delete the scheduled entry from the database so there won't be attempts for shutdown.
also if we scheduled 5 instances for shutdown but in reality there are 3, we will shutdown the intances from 1-3. the entries for shutdown for instance 4 and 5 won't be cleared from the database. when we increase the instances back to 5, the scheduled entries will be cleared from the database.
If we schedule 3 instances but there are 5, only the first 3 will be shutdown. the other 2 won't be shutdown

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we have to think to add some cleanup of such data from db because there is a case if we scale up instances and run for some time in this way and after several shutdown of instances, we decide to reduce app instances, it will schedule to shutdown for example 5 instances but after shutdown, startup of new application will be with 3 instances for example and data in db for 4 and 5 instance won't be deleted and if we decide again to increase instances, it will potentially start and try to shutdown instances 4 and 5 immediately.
Is there any guarantee that scheduler thread for monitoring for shutdown action does not run before bootstrapservlet where data for shutdown action will be deleted?

Comment on lines 69 to 83
private void shutdownApplication(ApplicationShutdown applicationShutdown) {
CompletableFuture.runAsync(() -> {
logProgressOfShuttingDown(applicationShutdown, Messages.SHUTTING_DOWN_APPLICATION_WITH_ID_AND_INDEX);
flowableFacade.shutdownJobExecutor();
})
.thenRun(() -> logProgressOfShuttingDown(applicationShutdown, Messages.SHUT_DOWN_APPLICATION_WITH_ID_AND_INDEX));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible here, exception to be thrown inside the async task, this will impact the DB state in a wrong way. Maybe add FAILED status for such cases.

@stiv03
Copy link
Contributor

stiv03 commented Jan 8, 2026

Also add some unit tests, cause now there is 0.0% Coverage on New Code

@Yavor16 Yavor16 force-pushed the application-shutdown-logic-update branch 4 times, most recently from 1879759 to 22db5eb Compare January 13, 2026 12:55
@Yavor16 Yavor16 force-pushed the application-shutdown-logic-update branch from 22db5eb to 92c2584 Compare January 23, 2026 06:33
instanceShutdownExecutor.execute(applicationGuid, i);
public void execute(String applicationId, int applicationInstanceCount) {
ApplicationShutdownScheduler applicationShutdownScheduler = getApplicationShutdownScheduler();
List<ApplicationShutdown> scheduledApplicationShutdowns = applicationShutdownScheduler.scheduleApplicationForShutdown(applicationId,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we have to think to add some cleanup of such data from db because there is a case if we scale up instances and run for some time in this way and after several shutdown of instances, we decide to reduce app instances, it will schedule to shutdown for example 5 instances but after shutdown, startup of new application will be with 3 instances for example and data in db for 4 and 5 instance won't be deleted and if we decide again to increase instances, it will potentially start and try to shutdown instances 4 and 5 immediately.
Is there any guarantee that scheduler thread for monitoring for shutdown action does not run before bootstrapservlet where data for shutdown action will be deleted?

LMCROSSITXSADEPLOY-3344

# Conflicts:
#	multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/Messages.java

# Conflicts:
#	multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/Messages.java
#	multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/resources/ApplicationShutdownResource.java

# Conflicts:
#	multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/Messages.java
#	multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/resources/ApplicationShutdownResource.java

# Conflicts:
#	multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/Messages.java
#	multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/resources/ApplicationShutdownResource.java
@Yavor16 Yavor16 force-pushed the application-shutdown-logic-update branch 2 times, most recently from c9e7df2 to e55774f Compare January 28, 2026 11:00
@Yavor16 Yavor16 force-pushed the application-shutdown-logic-update branch from e55774f to 492d215 Compare January 28, 2026 11:07
private void deleteLeftoverApplicationShutdowns(List<ApplicationShutdown> leftoverApplicationShutdowns) {
leftoverApplicationShutdowns.forEach(applicationShutdown -> applicationShutdownService.createQuery()
.id(applicationShutdown.getId())
.delete());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make it to be deleted all entries with single query instead of new db query for every entry.
Another approach for this is calculate older than timestamp in java code and execute db query with timestamp condition, in this way it will avoid processing in java code.

Comment on lines 35 to 36
deleteLeftoverApplicationShutdowns(leftoverApplicationShutdowns);
LOGGER.info(MessageFormat.format(Messages.DELETED_LEFTOVER_APPLICATION_SHUTDOWNS, leftoverApplicationShutdowns.size()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can also add a log for which shutdown is deleted

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the new implementation this is not possible anymore

return isTimeExceeded(applicationShutdown, DAY_IN_SECONDS);
}

private static boolean isTimeExceeded(ApplicationShutdown applicationShutdown, int seconds) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use Duration type here instead of int

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is changed now

Comment on lines 37 to 41
Instant secondsAfterStartedDate = Instant.from(applicationShutdown.getStartedAt()
.toInstant())
.plusSeconds(seconds);
Instant timeNow = Instant.now();
return timeNow.isAfter(secondsAfterStartedDate);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this double conversion .toInstant() necessary, also can .getStartedAt()be null and throw NPE?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is possible because when we create a new ApplicationShutdown we set the time every time


@Test
void testExecuteWithLeftoverApplications() {
Date timeBeforeTwoDays = new Date(1738061834);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont thinks this is 2 days ago :D

Copy link
Contributor Author

@Yavor16 Yavor16 Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a little more than two days :D. The test doesn't exist anymore


verify(applicationShutdownService, times(2)).createQuery();
verify(applicationShutdownQuery).list();
verify(applicationShutdownQuery).delete();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can also check for a specific applicationShutdown id to be sure that we r deleting the right one

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed this test

@Yavor16 Yavor16 force-pushed the application-shutdown-logic-update branch from 89e5530 to 52c689d Compare January 29, 2026 06:16
package org.cloudfoundry.multiapps.controller.persistence.dto;

import org.immutables.value.Value;
import java.util.Date;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last thing, can you replace usage of java.util.Date with java.time.LocalDateTime all object related to shutdown because this api is quite old and have different issues - https://programminghints.com/2017/05/still-using-java-util-date-dont/

I have checked that all other query classes is using LocalDateTime or ZonedDateTime for timestamp objects.

theghost5800
theghost5800 previously approved these changes Jan 29, 2026
@Yavor16 Yavor16 force-pushed the application-shutdown-logic-update branch 2 times, most recently from a040377 to 76f45db Compare January 29, 2026 10:54
@Yavor16 Yavor16 force-pushed the application-shutdown-logic-update branch from 76f45db to a2cdbf5 Compare January 29, 2026 11:00
@sonarqubecloud
Copy link

@Yavor16 Yavor16 merged commit 8445795 into master Jan 29, 2026
8 checks passed
@Yavor16 Yavor16 deleted the application-shutdown-logic-update branch January 29, 2026 12:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants