Sto provando a convertire la configurazione XML per l'utilizzo del framework delle attività di Spring in configurazione puramente di codice. Sono in grado di riprodurre la funzionalità ma ogni volta che spengo la guerra sul server Tomcat su cui vive l'utilità di pianificazione, si blocca (non si blocca con la configurazione XML). Ho eseguito il debug per ispezionare le istanze di scheduler ed executor, ma non vedo una differenza, quindi non sono sicuro di cosa potrebbe causarne il blocco.Conversione della configurazione XML del task Spring per la configurazione del codice
Ecco la configurazione XML che funziona:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd">
<task:executor id="com.work.gwx.pix.executor"
pool-size="${pix.job.executor.pool.size:1-40}"
queue-capacity="${pix.job.executor.queue.capacity:0}"
rejection-policy="CALLER_RUNS"/>
<task:scheduler id="com.work.gwx.pix.scheduler" pool-size="${pix.job.scheduler.pool.size:4}" />
<task:annotation-driven executor="com.work.gwx.pix.executor" scheduler="com.work.gwx.pix.scheduler" />
<bean id='queueProcessor' class="com.work.gwx.queueing.QueueProcessor" />
</beans>
Ecco il codice di configurazione:
@EnableAsync
@EnableScheduling
@Configuration
public class TaskConfiguration implements AsyncConfigurer, SchedulingConfigurer {
@Value("${pix.job.executor.max.pool.size:1}")
private int executorMaxPoolSize;
@Value("${pix.job.executor.queue.capacity:0}")
private int executorQueueCapacity;
@Value("${pix.job.scheduler.pool.size:4}")
private int schedulerPoolSize;
@Bean(destroyMethod = "shutdown")
public Executor pixTaskScheduler() {
final ScheduledThreadPoolExecutor ex = new ScheduledThreadPoolExecutor(schedulerPoolSize, new ThreadPoolTaskExecutor());
// ex.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
return ex;
}
@Bean
public Executor pixExecutor() {
final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(executorMaxPoolSize);
executor.setQueueCapacity(executorQueueCapacity);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setThreadFactory(new ThreadPoolTaskExecutor());
executor.initialize();
return executor;
}
@Override
public void configureTasks(final ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(pixTaskScheduler());
}
@Override
public Executor getAsyncExecutor() {
return pixExecutor();
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SimpleAsyncUncaughtExceptionHandler();
}
}
Quando uso setExecuteExistingDelayedTasksAfterShutdownPolicy(false)
nel codice di configurazione che fa arrestare, ma io sono preoccupato che la forza avere effetti negativi poiché è impostato su true quando viene eseguito tramite la configurazione XML. Inoltre, dovrei notare, la classe QueueProcessor sta facendo il lavoro che voglio e non mi dispiace se le esecuzioni in ritardo vengono cancellate - Non voglio che i thread in esecuzione attualmente vengano cancellati bruscamente.
Questo è il messaggio che ottengo quando si blocca:
GRAVI: L'applicazione web [/ pix-queue-processor] sembra avere ha iniziato una discussione chiamato [ThreadPoolTaskExecutor-1], ma non è riuscita a fermalo. È molto probabile che questo crei una perdita di memoria.
Qualche idea su cosa potrebbe causare l'impiccagione? Oppure, utilizzerei quel metodo commentato permettimi di fare ciò che voglio (non ucciderò un'attività in esecuzione ma annullerò i compiti in ritardo)?
Uno dei problemi che vedo è che stai impostando un nuovo 'ThreadPoolTaskExecutor' come' ThreadFactory'? Perché? Ora hai fondamentalmente 2 esecutori di compiti in cui uno è controllato e l'altro in realtà no. –
Un'altra cosa è perché non stai collegando il tuo 'TaskExecutor' al tuo 'TaskScheduler'? Che sta usando, ancora un altro' TaskExecutor non gestito'. –