package org.fluxtream.core.services.impl;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.fluxtream.core.aspects.FlxLogger;
import org.fluxtream.core.domain.UpdateWorkerTask;
import org.fluxtream.core.utils.JPAUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
* This is a helper service, hence part of the 'impl' package, that enforces local ('nested') persistence of entities
* whose lifecycle spans the calling methods entire execution time.
* User: candide
* Date: 14/08/14
* Time: 15:59
*/
@Service
@Transactional(readOnly=true)
public class WorkerDispatchServiceImpl implements WorkerDispatchService {
static FlxLogger logger = FlxLogger.getLogger(WorkerDispatchServiceImpl.class);
@PersistenceContext
EntityManager em;
@Autowired
@Qualifier("updateWorkersExecutor")
ThreadPoolTaskExecutor executor;
@Override
@Transactional(readOnly=false, propagation = Propagation.REQUIRES_NEW)
public List<UpdateWorkerTask> claimTasksForDispatch(int availableThreads, String serverUUID) {
List<UpdateWorkerTask> updateWorkerTasks = JPAUtils.findWithLimit(em, UpdateWorkerTask.class, "updateWorkerTasks.byStatus", 0, availableThreads, UpdateWorkerTask.Status.SCHEDULED, System.currentTimeMillis());
if (updateWorkerTasks.size() == 0) {
logger.debug("Nothing to do");
} else {
StringBuilder sb = new StringBuilder("claiming tasks for dispatch, ").append(" availableThreads=" + availableThreads).append(" message=\"adding " + updateWorkerTasks.size() + " update worker tasks\"").append(" activeCount=" + executor.getActiveCount() + " maxPoolSize=" + executor.getMaxPoolSize());
logger.info(sb);
for (int i = 0; i < updateWorkerTasks.size(); i++) {
UpdateWorkerTask task = updateWorkerTasks.get(i);
task.startTime = null;
task.endTime = null;
task.workerThreadName = null;
task.serverUUID = serverUUID;
task.status = UpdateWorkerTask.Status.IN_PROGRESS;
task.addAuditTrailEntry(new UpdateWorkerTask.AuditTrailEntry(new java.util.Date(), serverUUID));
}
}
return updateWorkerTasks;
}
@Override
@Transactional(readOnly=false, propagation = Propagation.REQUIRES_NEW)
public void unclaimTask(final long taskId) {
UpdateWorkerTask task = em.find(UpdateWorkerTask.class, taskId);
if (task!=null) {
task.serverUUID = null;
task.status = UpdateWorkerTask.Status.SCHEDULED;
}
}
}