package com.anjlab.spelling.web.services.workers; import org.apache.tapestry5.ioc.Invokable; import org.slf4j.Logger; import com.anjlab.spelling.web.entities.Task; import com.anjlab.spelling.web.services.managers.TaskManager; import com.anjlab.spelling.web.services.managers.WorkerManager; public class WorkerRoutine implements Invokable { private final Logger logger; private final Worker worker; private final TaskManager taskManager; private final WorkerManager workerManager; private volatile boolean workerReloading; public WorkerRoutine(Logger logger, Worker worker, TaskManager taskManager, WorkerManager workerManager) { this.logger = logger; this.worker = worker; this.taskManager = taskManager; this.workerManager = workerManager; } public void workerReloading() { this.workerReloading = true; } public Object invoke() { while (true) { try { workerReloading = false; worker.setRoutine(this); worker.cleanup(); worker.run(); workerManager.taskCompleted(worker); } catch (InterruptedException e) { logger.error("Interrupted exception", e); if (!workerReloading && (!worker.isTaskCancelled() || worker.isShuttingDown())) { logger.info("Task wasn't canceled. Exiting..."); Thread.currentThread().interrupt(); break; } else { logger.info("Worker task was interrupted, resuming to next task"); Thread.interrupted(); workerManager.taskCompleted(worker); } } catch (Exception e) { logger.error("Worker " + worker.getTaskType() + " failed with exception", e); if (e.getMessage().contains("Cannot open connection") || e.getMessage().contains("Unable to locate a single EntityManager")) { throw new RuntimeException(e); } Task task = worker.currentTask(); if (task != null) { int projectId = task.getProject().getId(); try { taskManager.cleanupTasksAfterError(projectId); } catch (Exception ex) { logger.error("Error performing tasks cleanup for project " + projectId, ex); } } } finally { logger.debug("Worker routine iteration completed"); if (worker.isShuttingDown()) { break; } } } logger.warn("Exiting worker routine"); worker.onExit(); return null; } }