package com.xiaopeng.map.schedule;
|
|
import com.xiaopeng.api.model.operation.XpElectronicFence;
|
import com.xiaopeng.map.service.XpElectronicFenceService;
|
import lombok.extern.slf4j.Slf4j;
|
import org.redisson.api.RLock;
|
import org.redisson.api.RedissonClient;
|
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.stereotype.Component;
|
|
import javax.annotation.Resource;
|
import java.time.LocalDateTime;
|
import java.util.List;
|
import java.util.concurrent.TimeUnit;
|
import java.util.stream.Collectors;
|
|
/**
|
* 电子围栏失效补偿定时任务
|
*/
|
@Slf4j
|
@Component
|
public class ElectronicFenceFailureCompensationTask {
|
|
private static final String LOCK_KEY = "MAP:ELECTRONIC_FENCE:FAILURE_COMPENSATE";
|
private static final String LOCK_KEY_ENABLE = "MAP:ELECTRONIC_FENCE:ENABLE_COMPENSATE";
|
private static final int LOCK_WAIT_SECONDS = 0;
|
private static final int LOCK_LEASE_SECONDS = 15;
|
|
@Resource
|
private XpElectronicFenceService xpElectronicFenceService;
|
|
@Resource
|
private RedissonClient redissonClient;
|
|
|
/**
|
* 定时任务 围栏失效补偿定时任务
|
*/
|
@Scheduled(fixedDelay = 10 * 1000L)
|
public void compensateExpiredFence() {
|
RLock lock = redissonClient.getLock(LOCK_KEY);
|
boolean locked = false;
|
try {
|
locked = lock.tryLock(LOCK_WAIT_SECONDS, LOCK_LEASE_SECONDS, TimeUnit.SECONDS);
|
if (!locked) {
|
return;
|
}
|
|
LocalDateTime now = LocalDateTime.now();
|
List<XpElectronicFence> expiredFenceList = xpElectronicFenceService.lambdaQuery()
|
.eq(XpElectronicFence::getFailureType, 2)
|
.le(XpElectronicFence::getFailureTime, now)
|
.in(XpElectronicFence::getStatus, 1, 2)
|
.list();
|
if (expiredFenceList == null || expiredFenceList.isEmpty()) {
|
return;
|
}
|
|
List<Long> electronicIds = expiredFenceList.stream()
|
.map(XpElectronicFence::getId)
|
.collect(Collectors.toList());
|
log.info("电子围栏失效补偿开始, count={}, ids={}", electronicIds.size(), electronicIds);
|
for (Long electronicId : electronicIds) {
|
try {
|
xpElectronicFenceService.expireFence(electronicId);
|
} catch (Exception e) {
|
log.error("电子围栏失效补偿单条处理异常, electronicId={}", electronicId, e);
|
}
|
}
|
log.info("电子围栏失效补偿完成, count={}, ids={}", electronicIds.size(), electronicIds);
|
} catch (InterruptedException e) {
|
Thread.currentThread().interrupt();
|
log.warn("电子围栏失效补偿任务获取锁被中断", e);
|
} catch (Exception e) {
|
log.error("电子围栏失效补偿任务执行异常", e);
|
} finally {
|
try {
|
if (locked && lock.isHeldByCurrentThread()) {
|
lock.unlock();
|
}
|
} catch (Exception e) {
|
log.warn("释放电子围栏失效补偿锁失败 lockKey={}", LOCK_KEY, e);
|
}
|
}
|
}
|
|
/**
|
* 围栏启动偿定时任务
|
*/
|
@Scheduled(fixedDelay = 10 * 1000L)
|
public void compensateEnableFence() {
|
RLock lock = redissonClient.getLock(LOCK_KEY_ENABLE);
|
boolean locked = false;
|
try {
|
locked = lock.tryLock(LOCK_WAIT_SECONDS, LOCK_LEASE_SECONDS, TimeUnit.SECONDS);
|
if (!locked) {
|
return;
|
}
|
List<XpElectronicFence> expiredFenceList = xpElectronicFenceService.lambdaQuery()
|
.eq(XpElectronicFence::getDeleted, 0)
|
.eq(XpElectronicFence::getStatus, 1)//围栏状态 0=草稿 1=待启用 2=启用中 3=已停用
|
.ge(XpElectronicFence::getFailureTime, LocalDateTime.now())//当前时间小于生效时间
|
.list();
|
if (expiredFenceList == null || expiredFenceList.isEmpty()) {
|
return;
|
}
|
List<Long> electronicIds = expiredFenceList.stream()
|
.map(XpElectronicFence::getId)
|
.collect(Collectors.toList());
|
log.info("电子围栏失效补偿开始, count={}, ids={}", electronicIds.size(), electronicIds);
|
for (Long electronicId : electronicIds) {
|
try {
|
xpElectronicFenceService.enableFence(electronicId);
|
} catch (Exception e) {
|
log.error("电子围栏失效补偿单条处理异常, electronicId={}", electronicId, e);
|
}
|
}
|
log.info("电子围栏失效补偿完成, count={}, ids={}", electronicIds.size(), electronicIds);
|
} catch (InterruptedException e) {
|
Thread.currentThread().interrupt();
|
log.warn("电子围栏失效补偿任务获取锁被中断", e);
|
} catch (Exception e) {
|
log.error("电子围栏失效补偿任务执行异常", e);
|
} finally {
|
try {
|
if (locked && lock.isHeldByCurrentThread()) {
|
lock.unlock();
|
}
|
} catch (Exception e) {
|
log.warn("释放电子围栏失效补偿锁失败 lockKey={}", LOCK_KEY, e);
|
}
|
}
|
}
|
}
|