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 expiredFenceList = xpElectronicFenceService.lambdaQuery() .eq(XpElectronicFence::getFailureType, 2) .le(XpElectronicFence::getFailureTime, now) .in(XpElectronicFence::getStatus, 1, 2) .list(); if (expiredFenceList == null || expiredFenceList.isEmpty()) { return; } List 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 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 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); } } } }