package eu.openaire.urls_controller.components; import eu.openaire.urls_controller.services.FullTextsServiceImpl; import eu.openaire.urls_controller.util.GenericUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @Component public class ScheduledTasks { private static final Logger logger = LoggerFactory.getLogger(ScheduledTasks.class); @Scheduled(fixedDelay = 3_600_000) // Execute this method 1 hour after the last execution, in order for some tasks to have been gathered. //@Scheduled(fixedDelay = 20_000) // Just for testing (every 20 secs). public void executeBackgroundTasks() { List> tempList = new ArrayList<>(FullTextsServiceImpl.backgroundCallableTasks); // Copy the list in order to know what was executed and delete only that data later. // So the items added while this execution happens, will be left in the list, while the other will be deleted. int numOfTasks = tempList.size(); // Since the temp-list is a deep-copy and not a reference, new tasks that are added will not be executed. if ( numOfTasks == 0 ) return; logger.debug(numOfTasks + " background tasks were found inside the \"backgroundCallableTasks\" list and are about to be executed."); // Execute the tasks and wait for them to finish. try { List> futures = FullTextsServiceImpl.backgroundExecutor.invokeAll(tempList); int sizeOfFutures = futures.size(); for ( int i = 0; i < sizeOfFutures; ++i ) { try { Boolean value = futures.get(i).get(); // Get and see if an exception is thrown.. // Add check for the value, if wanted.. (we don't care at the moment) } catch (ExecutionException ee) { String stackTraceMessage = GenericUtils.getSelectiveStackTrace(ee, null, 15); // These can be serious errors like an "out of memory exception" (Java HEAP). logger.error("Task_" + (i+1) + " failed with: " + ee.getMessage() + "\n" + stackTraceMessage); } catch (CancellationException ce) { logger.error("Task_" + (i+1) + " was cancelled: " + ce.getMessage()); } catch (IndexOutOfBoundsException ioobe) { logger.error("IOOBE for task_" + i + " in the futures-list! " + ioobe.getMessage()); } finally { FullTextsServiceImpl.backgroundCallableTasks.remove(tempList.get(i)); // Remove this object from the global list. Do not use indexes, since they will be different after each deletion and addition. } } } catch (Exception e) { logger.error("", e); } } }