Когда приложение остановлено (
Код: Выделить всё
CTRL-C
Несмотря на то, что сочетание клавиш CTRL-C дает приложению достаточно времени для корректной остановки заданий, результат тот же, что и уничтожение -9.
Я нашел способ (см. ниже) корректно остановить все задания, когда приложение завершается с помощью CTRL-C, но хотелось бы знать, есть ли лучший/более простой способ достичь этой цели.
Все, что приведено ниже, представляет собой документацию о том, как мне удалось остановить задания. p>
В записи блога 부알프레도 JobExecutionListener используется для регистрации перехватчиков завершения работы, которые должны останавливать задания:
Код: Выделить всё
public class ProcessShutdownListener implements JobExecutionListener {
private final JobOperator jobOperator;
ProcessShutdownListener(JobOperator jobOperator) { this.jobOperator = jobOperator; }
@Override public void afterJob(JobExecution jobExecution) { /* do nothing. */ }
@Override
public void beforeJob(final JobExecution jobExecution) {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
super.run();
try {
jobOperator.stop(jobExecution.getId());
while(jobExecution.isRunning()) {
try { Thread.sleep(100); } catch (InterruptedException e) {}
}
} catch (NoSuchJobExecutionException | JobExecutionNotRunningException e) { /* ignore */ }
}
});
}
}
Без этого PostProcessor jobOperator не смог бы найти работу.
(
Код: Выделить всё
NoSuchJobException: No job configuration with the name [job1] was registered
Код: Выделить всё
@Bean
public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor(JobRegistry jobRegistry) {
JobRegistryBeanPostProcessor postProcessor = new JobRegistryBeanPostProcessor();
postProcessor.setJobRegistry(jobRegistry);
return postProcessor;
}
Код: Выделить всё
org.h2.jdbc.JdbcSQLNonTransientConnectionException: Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL)
Код: Выделить всё
Processing item 2 before
Shutdown Hook is running !
2021-02-08 22:39:48.950 INFO 12676 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2021-02-08 22:39:49.218 INFO 12676 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
Processing item 3 before
Exception in thread "Thread-3" org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30004ms.
Окончательный ProcessShutdownListener выглядит так:
Код: Выделить всё
@Component
public class ProcessShutdownListener implements JobExecutionListener, SmartLifecycle {
private final JobOperator jobOperator;
public ProcessShutdownListener(JobOperator jobOperator) { this.jobOperator = jobOperator; }
@Override
public void afterJob(JobExecution jobExecution) { /* do nothing. */ }
private static final List runnables = new ArrayList();
@Override
public void beforeJob(final JobExecution jobExecution) {
runnables.add(() -> {
try {
if (!jobOperator.stop(jobExecution.getId())) return;
while (jobExecution.isRunning()) {
try {
Thread.sleep(100);
} catch (InterruptedException ignored) { /* ignore */ }
}
} catch (NoSuchJobExecutionException | JobExecutionNotRunningException e) { /* ignore */ }
});
}
@Override
public void start() {}
@Override
public void stop() {
// runnables.stream()
// .parallel()
// .forEach(Runnable::run);
runnables.forEach(Runnable::run);
}
@Override
public boolean isRunning() { return true; }
@Override
public boolean isAutoStartup() { return true; }
@Override
public void stop(Runnable callback) { stop(); callback.run(); }
@Override
public int getPhase() { return Integer.MAX_VALUE; }
}
Код: Выделить всё
@Bean
public Job job(JobBuilderFactory jobs,
ProcessShutdownListener processShutdownListener) {
return jobs.get("job1")
.listener(processShutdownListener)
.start(step(null))
.build();
}
Подробнее здесь: https://stackoverflow.com/questions/661 ... own-ctrl-c