✨ 定时清理未使用的 tag.
This commit is contained in:
@@ -3,6 +3,9 @@ package com.orion.ops.module.infra.dao;
|
||||
import com.orion.ops.framework.mybatis.core.mapper.IMapper;
|
||||
import com.orion.ops.module.infra.entity.domain.TagDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 标签枚举 Mapper 接口
|
||||
@@ -14,4 +17,12 @@ import org.apache.ibatis.annotations.Mapper;
|
||||
@Mapper
|
||||
public interface TagDAO extends IMapper<TagDO> {
|
||||
|
||||
/**
|
||||
* 获取未使用的标签
|
||||
*
|
||||
* @param days days
|
||||
* @return tagId
|
||||
*/
|
||||
List<TagDO> selectUnusedTag(@Param("days") Integer days);
|
||||
|
||||
}
|
||||
|
||||
@@ -46,4 +46,9 @@ public interface TagService {
|
||||
*/
|
||||
Integer deleteTagByIdList(List<Long> idList);
|
||||
|
||||
/**
|
||||
* 清理未使用的 tag
|
||||
*/
|
||||
void clearUnusedTag();
|
||||
|
||||
}
|
||||
|
||||
@@ -32,6 +32,11 @@ import java.util.stream.Collectors;
|
||||
@Service
|
||||
public class TagServiceImpl implements TagService {
|
||||
|
||||
/**
|
||||
* 未使用的天数
|
||||
*/
|
||||
private static final Integer UN_USED_DAYS = 3;
|
||||
|
||||
@Resource
|
||||
private TagDAO tagDAO;
|
||||
|
||||
@@ -113,4 +118,27 @@ public class TagServiceImpl implements TagService {
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearUnusedTag() {
|
||||
// 查询
|
||||
List<TagDO> tagList = tagDAO.selectUnusedTag(UN_USED_DAYS);
|
||||
if (tagList.isEmpty()) {
|
||||
log.info("TagService.clearUnusedTag isEmpty");
|
||||
return;
|
||||
}
|
||||
// 删除数据
|
||||
List<Long> tagIdList = tagList.stream()
|
||||
.map(TagDO::getId)
|
||||
.collect(Collectors.toList());
|
||||
int effect = tagDAO.deleteBatchIds(tagIdList);
|
||||
log.info("TagService.clearUnusedTag deleted count: {}, deleted: {}, tags: {}", tagIdList.size(), effect, tagIdList);
|
||||
// 删除缓存
|
||||
List<String> cacheKeys = tagList.stream()
|
||||
.map(TagDO::getType)
|
||||
.distinct()
|
||||
.map(TagCacheKeyDefine.TAG_NAME::format)
|
||||
.collect(Collectors.toList());
|
||||
RedisLists.delete(cacheKeys);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.orion.ops.module.infra.task;
|
||||
|
||||
import com.orion.ops.module.infra.service.TagService;
|
||||
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;
|
||||
|
||||
/**
|
||||
* tag 定时清理任务
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2024/4/15 23:50
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class TagAutoClearTask {
|
||||
|
||||
/**
|
||||
* 分布式锁名称
|
||||
*/
|
||||
private static final String LOCK_KEY = "tag:clear:lock";
|
||||
|
||||
@Resource
|
||||
private RedissonClient redissonClient;
|
||||
|
||||
@Resource
|
||||
private TagService tagService;
|
||||
|
||||
/**
|
||||
* 定时清理未引用的 tag
|
||||
*/
|
||||
@Scheduled(cron = "0 0 2 * * ?")
|
||||
public void clear() {
|
||||
log.info("TagAutoClearTask.clear start");
|
||||
// 获取锁
|
||||
RLock lock = redissonClient.getLock(LOCK_KEY);
|
||||
// 未获取到直接返回
|
||||
if (!lock.tryLock()) {
|
||||
log.info("TagAutoClearTask.clear locked end");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// 清理
|
||||
tagService.clearUnusedTag();
|
||||
log.info("TagAutoClearTask.clear finish");
|
||||
} catch (Exception e) {
|
||||
log.error("TagAutoClearTask.clear error", e);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,4 +19,14 @@
|
||||
id, name, type, create_time, update_time, creator, updater, deleted
|
||||
</sql>
|
||||
|
||||
<select id="selectUnusedTag" resultMap="BaseResultMap">
|
||||
SELECT t.id, t.type
|
||||
FROM tag t
|
||||
LEFT JOIN tag_rel tr ON t.id = tr.tag_id AND tr.deleted = 0
|
||||
WHERE t.create_time <![CDATA[ < ]]> DATE_SUB(NOW(), INTERVAL #{days} DAY)
|
||||
AND tr.tag_id IS NULL
|
||||
AND t.deleted = 0
|
||||
GROUP BY t.id
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
const logViewRef = ref();
|
||||
const currentHostExecId = ref();
|
||||
const statusIntervalId = ref();
|
||||
const finishIntervalId = ref();
|
||||
const execLog = ref<ExecLogQueryResponse>();
|
||||
const appender = ref<ILogAppender>();
|
||||
|
||||
@@ -60,8 +59,6 @@
|
||||
record.status === execStatus.RUNNING) {
|
||||
// 注册状态轮询
|
||||
statusIntervalId.value = setInterval(fetchTaskStatus, 5000);
|
||||
// 注册完成时间轮询
|
||||
finishIntervalId.value = setInterval(setTaskFinishTime, 1000);
|
||||
}
|
||||
// 打开日志
|
||||
nextTick(() => {
|
||||
@@ -95,9 +92,8 @@
|
||||
if (hostStatus) {
|
||||
host.status = hostStatus.status;
|
||||
host.startTime = hostStatus.startTime;
|
||||
if (hostStatus.finishTime) {
|
||||
host.finishTime = hostStatus.finishTime;
|
||||
}
|
||||
// 使用时间
|
||||
host.finishTime = host.finishTime || Date.now();
|
||||
host.exitStatus = hostStatus.exitStatus;
|
||||
host.errorMessage = hostStatus.errorMessage;
|
||||
}
|
||||
@@ -154,8 +150,6 @@
|
||||
const clearAllInterval = () => {
|
||||
// 关闭状态轮询
|
||||
clearInterval(statusIntervalId.value);
|
||||
// 关闭使用时间轮询
|
||||
clearInterval(finishIntervalId.value);
|
||||
};
|
||||
|
||||
// 加载字典值
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
<span class="tag-value">{{ host.exitStatus }}</span>
|
||||
</a-tag>
|
||||
<!-- 持续时间 -->
|
||||
<a-tag color="arcoblue" title="持续时间">
|
||||
<a-tag v-if="host.startTime"
|
||||
color="arcoblue"
|
||||
title="持续时间">
|
||||
<template #icon>
|
||||
<icon-loading v-if="host.status === execHostStatus.WAITING || host.status === execHostStatus.RUNNING" />
|
||||
<icon-clock-circle v-else />
|
||||
|
||||
Reference in New Issue
Block a user