com.hengyi.japp.execution.service.BackendJobService.java Source code

Java tutorial

Introduction

Here is the source code for com.hengyi.japp.execution.service.BackendJobService.java

Source

/*
 * 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();
    }
}