/**
* 短信 任务调度器
*/
@Slf4j
@Component
public class SmsScheduledExecutor {
/**
* 核心线程调度器
*/
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(3);
@Getter
private final ConcurrentHashMap<String, ScheduledFuture<?>> scheduledFutureMap = new ConcurrentHashMap<>();
@Autowired
private ChargeWarnRuleService chargeWarnRuleService;
/**
* 在事务之后 开启执行器
*
* @param chargeWarnRule
* @param uuid
* @throws CodeException
*/
public synchronized void startTask(ChargeWarnRule chargeWarnRule, String uuid) throws CodeException {
if (uuid ==null){
throw new CodeException(HttpStatus.BAD_REQUEST.value(), "uuid不能为空");
}
if (chargeWarnRule == null) {
throw new CodeException(HttpStatus.BAD_REQUEST.value(), "传入警告规则参数不能为空");
}
ScheduledFuture<?> scheduledFuture = scheduledFutureMap.get(uuid);
if (scheduledFuture != null) {
throw new CodeException(HttpStatus.BAD_REQUEST.value(), "执行器已经启动,不必再次启动 执行器ID" + uuid);
}
byte enable = chargeWarnRule.getEnable();
if (enable == 0) {
throw new CodeException(HttpStatus.BAD_REQUEST.value(), "报警规则处于禁用状态,不允许启用 规则名称:" + chargeWarnRule.getRuleName());
}
byte warnCount = chargeWarnRule.getWarnCount();
long delayMorningEightMillis = calculateDelayMorningEightMillis();
long period= calculateInternalMillis(warnCount);
ScheduledFuture<?> task = scheduler.scheduleAtFixedRate(createTask(chargeWarnRule), delayMorningEightMillis, period, TimeUnit.MILLISECONDS);
scheduledFutureMap.put(uuid, task);
}
/**
* 停止执行器
*
* @param uuid
* @throws CodeException
*/
public synchronized boolean stopTask( String uuid) throws CodeException {
if (uuid ==null){
throw new CodeException(HttpStatus.BAD_REQUEST.value(), "uuid不能为空");
}
ScheduledFuture<?> scheduledFuture = scheduledFutureMap.get(uuid);
if (scheduledFuture == null) {
throw new CodeException(HttpStatus.BAD_REQUEST.value(), "执行器已经停止,不必再次停止 执行器ID" + uuid);
}
if (scheduledFuture.isDone() || scheduledFuture.isCancelled()){
scheduledFutureMap.remove(uuid);
return true;
}
boolean cancel = scheduledFuture.cancel(true);
if (cancel){
scheduledFutureMap.remove(uuid);
}else {
throw new CodeException(HttpStatus.BAD_REQUEST.value(), "执行器停止失败 执行器ID 请重新停止" + uuid);
}
return cancel;
}
/**
* 停止执行器
*
* @param uuid
* @throws CodeException
*/
public boolean getTaskRunningStatus( String uuid) throws CodeException {
if (uuid ==null){
throw new CodeException(HttpStatus.BAD_REQUEST.value(), "uuid不能为空");
}
ScheduledFuture<?> scheduledFuture = scheduledFutureMap.get(uuid);
if (scheduledFuture == null) {
return false;
}
if (scheduledFuture.isDone() || scheduledFuture.isCancelled()){
return false;
}
return true;
}
private Runnable createTask(ChargeWarnRule chargeWarnRule) {
return ()->{
log.info("发送了一次短信"+DateUtil.now()+"thread "+Thread.currentThread().getName());
};
}
/**
* 计算到早上8点的毫秒值
* @return
*/
private long calculateDelayMorningEightMillis() {
DateTime date = DateUtil.date();
int hour = DateUtil.hour(date, true);
DateTime during = DateUtil.dateNew(date);
during.setField(DateField.HOUR, 8);
during.setField(DateField.MINUTE, 0);
during.setField(DateField.SECOND, 0);
during.setField(DateField.MILLISECOND, 0);
if (hour >= 8) {
during.offset(DateField.DAY_OF_MONTH, 1);
}
return DateUtil.betweenMs(date, during);
}
/**
* 计算一天分成多少个毫秒值
* @param count
* @return
*/
private long calculateInternalMillis(int count) {
return 1000L * 60 * 60 * 24 / count;
}
}