Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.hengyi.japp.execution.service; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.hengyi.japp.event.InitEvent; import static com.hengyi.japp.execution.Util.getMilliSecondsDelay; import com.hengyi.japp.execution.data.TaskStatus; import com.hengyi.japp.execution.data.TaskType; import com.hengyi.japp.execution.domain.Task; import com.hengyi.japp.execution.domain.TaskSms; import com.hengyi.japp.execution.domain.Task_; import com.hengyi.japp.execution.exception.SmsSendFailureException; import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import javax.annotation.PreDestroy; import javax.annotation.Resource; import javax.ejb.AccessTimeout; import javax.ejb.Asynchronous; import javax.ejb.EJB; import javax.ejb.Lock; import javax.ejb.LockType; import javax.ejb.Schedule; import javax.ejb.Singleton; import javax.ejb.Startup; import javax.enterprise.concurrent.ManagedScheduledExecutorService; import javax.enterprise.event.Observes; import javax.inject.Inject; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import org.joda.time.LocalDate; import org.slf4j.Logger; /** * * @author jzb */ @Startup @Singleton @Lock(LockType.READ) @AccessTimeout(value = -1) public class BackendJobService { @Inject private Logger log; @Inject private JobFactory jobFactory; @Resource private ManagedScheduledExecutorService executor; @PersistenceContext private EntityManager em; @EJB private SmsService smsService; // ? private static final Date applicationStartDate = new Date(); // Id??job???job private static final Map<String, List<ScheduledFuture<?>>> taskSfsMap = Maps.newConcurrentMap(); @Asynchronous public void onInitEvent(@Observes InitEvent event) { executor.schedule(new Runnable() { @Override public void run() { log.info("==============???Job=============="); scheduleAllTask(applicationStartDate); } }, 60, TimeUnit.SECONDS); } @Schedule public void dailyJob() { log.info("==============?0?=============="); Date currentDate = new Date(); if (LocalDate.fromDateFields(currentDate).isBefore(LocalDate.fromDateFields(applicationStartDate))) { return; } for (String id : taskSfsMap.keySet()) { cancelScheduleTask(id); } scheduleAllTask(currentDate); } private void scheduleAllTask(Date date) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Task> cq = cb.createQuery(Task.class).distinct(true); Root<Task> root = cq.from(Task.class); List<Predicate> ps = Lists.newArrayListWithCapacity(2); ps.add(root.get(Task_.status).in(TaskStatus.INIT, TaskStatus.RUN)); ps.add(cb.lessThanOrEqualTo(root.get(Task_.startDate), date)); ps.add(cb.notEqual(root.get(Task_.type), TaskType.NONE)); for (Task task : em.createQuery(cq.where(ps.toArray(new Predicate[ps.size()]))).getResultList()) { schedule(task); } } @Lock public void schedule(Task task) { if (!task.isNeedNotice()) { return; } String taskId = task.getId(); cancelScheduleTask(taskId); List<ScheduledFuture<?>> sfs = Lists.newArrayList(); taskSfsMap.put(taskId, sfs); for (TaskSms taskSms : task.getTaskSmses()) { sfs.add(executor.schedule(jobFactory.taskSmsSend(taskSms), getMilliSecondsDelay(taskSms.getSendDateTime()), TimeUnit.MILLISECONDS)); } } public void cancelScheduleTask(String taskId) { List<ScheduledFuture<?>> scheduledFutures = taskSfsMap.get(taskId); if (scheduledFutures == null) { return; } for (ScheduledFuture<?> scheduledFuture : scheduledFutures) { scheduledFuture.cancel(false); } taskSfsMap.remove(taskId); } public void scheduleTaskSmsTimeOut(String taskSmsId) { // TODO ?? TaskSms taskSms = em.find(TaskSms.class, taskSmsId); if (!taskSms.getTask().isTeam()) { return; } ScheduledFuture<?> sf = executor.schedule(jobFactory.taskSmsTimeOut(taskSms), getMilliSecondsDelay(taskSms.getReactionNoneTimeOutDateTime()), TimeUnit.MILLISECONDS); taskSfsMap.get(taskSms.getTask().getId()).add(sf); } public void taskSmsHandle(String taskSmsHandleId) { try { smsService.taskSmsHandle(taskSmsHandleId); } catch (SmsSendFailureException e) { // TODO reaction ??,?? } } @PreDestroy public void destroy() { log.info("==============???=============="); for (String id : taskSfsMap.keySet()) { cancelScheduleTask(id); } executor.shutdown(); } }