-
Notifications
You must be signed in to change notification settings - Fork 42
Update application shutdown logic #1760
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
31b61f2 to
8da103c
Compare
...loudfoundry/multiapps/controller/core/application/shutdown/ApplicationShutdownScheduler.java
Outdated
Show resolved
Hide resolved
...iapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/Messages.java
Outdated
Show resolved
Hide resolved
...loudfoundry/multiapps/controller/core/application/shutdown/ApplicationShutdownScheduler.java
Outdated
Show resolved
Hide resolved
...src/main/java/org/cloudfoundry/multiapps/controller/persistence/dto/ApplicationShutdown.java
Outdated
Show resolved
Hide resolved
.../main/java/org/cloudfoundry/multiapps/controller/persistence/dto/ApplicationShutdownDto.java
Outdated
Show resolved
Hide resolved
...t/src/main/java/org/cloudfoundry/multiapps/controller/shutdown/client/util/ShutdownUtil.java
Outdated
Show resolved
Hide resolved
...t/src/main/java/org/cloudfoundry/multiapps/controller/shutdown/client/util/ShutdownUtil.java
Outdated
Show resolved
Hide resolved
| instanceShutdownExecutor.execute(applicationGuid, i); | ||
| public void execute(String applicationId, int applicationInstanceCount) { | ||
| ApplicationShutdownScheduler applicationShutdownScheduler = getApplicationShutdownScheduler(); | ||
| List<ApplicationShutdown> scheduledApplicationShutdowns = applicationShutdownScheduler.scheduleApplicationForShutdown(applicationId, |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
...in/java/org/cloudfoundry/multiapps/controller/web/resources/ApplicationShutdownResource.java
Show resolved
Hide resolved
...-web/src/main/java/org/cloudfoundry/multiapps/controller/web/bootstrap/BootstrapServlet.java
Outdated
Show resolved
Hide resolved
...loudfoundry/multiapps/controller/core/application/shutdown/ApplicationShutdownScheduler.java
Outdated
Show resolved
Hide resolved
...a/org/cloudfoundry/multiapps/controller/persistence/services/ApplicationShutdownService.java
Outdated
Show resolved
Hide resolved
.../main/java/org/cloudfoundry/multiapps/controller/persistence/dto/ApplicationShutdownDto.java
Outdated
Show resolved
Hide resolved
...g/cloudfoundry/multiapps/controller/persistence/query/impl/ApplicationShutdownQueryImpl.java
Outdated
Show resolved
Hide resolved
...src/main/java/org/cloudfoundry/multiapps/controller/process/jobs/ApplicationShutdownJob.java
Outdated
Show resolved
Hide resolved
| 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)); | ||
| } |
There was a problem hiding this comment.
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.
|
Also add some unit tests, cause now there is 0.0% Coverage on New Code |
1879759 to
22db5eb
Compare
22db5eb to
92c2584
Compare
...src/main/java/org/cloudfoundry/multiapps/controller/process/jobs/ApplicationShutdownJob.java
Show resolved
Hide resolved
| instanceShutdownExecutor.execute(applicationGuid, i); | ||
| public void execute(String applicationId, int applicationInstanceCount) { | ||
| ApplicationShutdownScheduler applicationShutdownScheduler = getApplicationShutdownScheduler(); | ||
| List<ApplicationShutdown> scheduledApplicationShutdowns = applicationShutdownScheduler.scheduleApplicationForShutdown(applicationId, |
There was a problem hiding this comment.
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?
...g/cloudfoundry/multiapps/controller/persistence/services/ApplicationShutdownServiceTest.java
Outdated
Show resolved
Hide resolved
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
c9e7df2 to
e55774f
Compare
e55774f to
492d215
Compare
| private void deleteLeftoverApplicationShutdowns(List<ApplicationShutdown> leftoverApplicationShutdowns) { | ||
| leftoverApplicationShutdowns.forEach(applicationShutdown -> applicationShutdownService.createQuery() | ||
| .id(applicationShutdown.getId()) | ||
| .delete()); |
There was a problem hiding this comment.
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.
| deleteLeftoverApplicationShutdowns(leftoverApplicationShutdowns); | ||
| LOGGER.info(MessageFormat.format(Messages.DELETED_LEFTOVER_APPLICATION_SHUTDOWNS, leftoverApplicationShutdowns.size())); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
| Instant secondsAfterStartedDate = Instant.from(applicationShutdown.getStartedAt() | ||
| .toInstant()) | ||
| .plusSeconds(seconds); | ||
| Instant timeNow = Instant.now(); | ||
| return timeNow.isAfter(secondsAfterStartedDate); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed this test
89e5530 to
52c689d
Compare
| package org.cloudfoundry.multiapps.controller.persistence.dto; | ||
|
|
||
| import org.immutables.value.Value; | ||
| import java.util.Date; |
There was a problem hiding this comment.
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.
d0fe23b to
62d9735
Compare
a040377 to
76f45db
Compare
76f45db to
a2cdbf5
Compare
|



No description provided.