fix: 解决 ConfigServiceImpl 与 SiteSnapshotServiceImpl 循环依赖
- 移除 SiteSnapshotServiceImpl 对 ConfigService 的依赖,直接使用 SiteConfigMapper - ConfigServiceImpl/SitePagesServiceImpl/RiskRuleServiceImpl 改用 ApplicationEvent 异步触发快照更新 - 新增 SnapshotUpdateEvent 和 SnapshotUpdateListener - ParApplication 添加 @EnableAsync 支持异步事件处理 - AdminController 中 updateSnapshot 调用改为发布事件
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
package com.par.core.event;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 快照更新事件
|
||||
* 当脚本、页面配置或风险规则发生变更时触发
|
||||
*/
|
||||
@Getter
|
||||
public class SnapshotUpdateEvent {
|
||||
|
||||
private final String siteId;
|
||||
|
||||
public SnapshotUpdateEvent(String siteId) {
|
||||
this.siteId = siteId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.par.core.event;
|
||||
|
||||
import com.par.core.service.SiteSnapshotService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 快照更新事件监听器
|
||||
* 异步处理,避免阻塞主流程
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class SnapshotUpdateListener {
|
||||
|
||||
private final SiteSnapshotService snapshotService;
|
||||
|
||||
@Async
|
||||
@EventListener
|
||||
public void handleSnapshotUpdate(SnapshotUpdateEvent event) {
|
||||
try {
|
||||
snapshotService.updateSnapshot(event.getSiteId());
|
||||
} catch (Exception e) {
|
||||
log.warn("快照更新失败 siteId={}: {}", event.getSiteId(), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,13 @@ import com.par.common.util.HmacUtil;
|
||||
import com.par.core.dto.SiteConfigDTO;
|
||||
import com.par.core.entity.SiteConfig;
|
||||
import com.par.core.enums.ConfigStatus;
|
||||
import com.par.core.event.SnapshotUpdateEvent;
|
||||
import com.par.core.mapper.SiteConfigMapper;
|
||||
import com.par.core.service.ConfigService;
|
||||
import com.par.core.service.ManifestVersionService;
|
||||
import com.par.core.service.SiteSnapshotService;
|
||||
import com.par.core.storage.CachedStorageService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
@@ -22,16 +23,16 @@ public class ConfigServiceImpl implements ConfigService {
|
||||
private final ManifestVersionService versionService;
|
||||
private final SiteConfigMapper siteConfigMapper;
|
||||
private final CachedStorageService storageService;
|
||||
private final SiteSnapshotService snapshotService;
|
||||
private final ApplicationEventPublisher eventPublisher;
|
||||
|
||||
public ConfigServiceImpl(ManifestVersionService versionService,
|
||||
SiteConfigMapper siteConfigMapper,
|
||||
CachedStorageService storageService,
|
||||
SiteSnapshotService snapshotService) {
|
||||
ApplicationEventPublisher eventPublisher) {
|
||||
this.versionService = versionService;
|
||||
this.siteConfigMapper = siteConfigMapper;
|
||||
this.storageService = storageService;
|
||||
this.snapshotService = snapshotService;
|
||||
this.eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -89,8 +90,8 @@ public class ConfigServiceImpl implements ConfigService {
|
||||
|
||||
siteConfigMapper.insert(config);
|
||||
versionService.increment(siteId);
|
||||
// 触发快照更新(异步更新 draft)
|
||||
try { snapshotService.updateSnapshot(siteId); } catch (Exception e) { log.warn("快照更新失败 siteId={}: {}", siteId, e.getMessage()); }
|
||||
// 发布事件,异步触发快照更新
|
||||
eventPublisher.publishEvent(new SnapshotUpdateEvent(siteId));
|
||||
log.info("Config submitted: siteId={}, version={}, id={}, scriptPath={}", siteId, version, config.getId(), scriptPath);
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -3,12 +3,13 @@ package com.par.core.service.impl;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.par.core.entity.RiskRule;
|
||||
import com.par.core.event.SnapshotUpdateEvent;
|
||||
import com.par.core.mapper.RiskRuleMapper;
|
||||
import com.par.core.service.ManifestVersionService;
|
||||
import com.par.core.service.RiskRuleService;
|
||||
import com.par.core.service.SiteSnapshotService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
@@ -22,7 +23,7 @@ public class RiskRuleServiceImpl implements RiskRuleService {
|
||||
private final RiskRuleMapper mapper;
|
||||
private final com.par.core.storage.CachedStorageService storageService;
|
||||
private final com.par.core.service.SiteService siteService;
|
||||
private final SiteSnapshotService snapshotService;
|
||||
private final ApplicationEventPublisher eventPublisher;
|
||||
private static final ObjectMapper om = new ObjectMapper();
|
||||
|
||||
private RiskRule findByIdentifier(String identifier) {
|
||||
@@ -122,11 +123,10 @@ public class RiskRuleServiceImpl implements RiskRuleService {
|
||||
.filter(s -> s.getSiteType() != null && siteType.equals(s.getSiteType().getValue()))
|
||||
.toList();
|
||||
for (var site : sites) {
|
||||
try { snapshotService.updateSnapshot(site.getSiteId()); }
|
||||
catch (Exception e) { log.warn("快照更新失败 siteId={}: {}", site.getSiteId(), e.getMessage()); }
|
||||
eventPublisher.publishEvent(new SnapshotUpdateEvent(site.getSiteId()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("批量快照更新失败 siteType={}: {}", siteType, e.getMessage());
|
||||
log.warn("批量快照更新事件发布失败 siteType={}: {}", siteType, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,13 @@ package com.par.core.service.impl;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.par.core.entity.SitePages;
|
||||
import com.par.core.event.SnapshotUpdateEvent;
|
||||
import com.par.core.mapper.SitePagesMapper;
|
||||
import com.par.core.service.ManifestVersionService;
|
||||
import com.par.core.service.SitePagesService;
|
||||
import com.par.core.service.SiteSnapshotService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
@@ -21,7 +22,7 @@ public class SitePagesServiceImpl implements SitePagesService {
|
||||
private final ManifestVersionService versionService;
|
||||
private final SitePagesMapper mapper;
|
||||
private final com.par.core.storage.CachedStorageService storageService;
|
||||
private final SiteSnapshotService snapshotService;
|
||||
private final ApplicationEventPublisher eventPublisher;
|
||||
private static final ObjectMapper om = new ObjectMapper();
|
||||
|
||||
@Override
|
||||
@@ -84,8 +85,8 @@ public class SitePagesServiceImpl implements SitePagesService {
|
||||
String storagePath = String.format("pages/%s/v%s.json", siteId, version);
|
||||
storageService.store(storagePath, json);
|
||||
versionService.increment(siteId);
|
||||
// 触发快照更新
|
||||
try { snapshotService.updateSnapshot(siteId); } catch (Exception e) { log.warn("快照更新失败 siteId={}: {}", siteId, e.getMessage()); }
|
||||
// 发布事件,异步触发快照更新
|
||||
eventPublisher.publishEvent(new SnapshotUpdateEvent(siteId));
|
||||
log.info("页面配置已保存: siteId={}, version={}, path={}", siteId, version, storagePath);
|
||||
} catch (Exception e) {
|
||||
log.error("保存页面配置失败 siteId={}", siteId, e);
|
||||
|
||||
@@ -11,7 +11,6 @@ import com.par.core.mapper.RiskRuleMapper;
|
||||
import com.par.core.mapper.SiteConfigMapper;
|
||||
import com.par.core.mapper.SiteMapper;
|
||||
import com.par.core.mapper.SiteSnapshotMapper;
|
||||
import com.par.core.service.ConfigService;
|
||||
import com.par.core.service.SitePagesService;
|
||||
import com.par.core.service.SiteSnapshotService;
|
||||
import com.par.core.storage.CachedStorageService;
|
||||
@@ -36,7 +35,6 @@ public class SiteSnapshotServiceImpl implements SiteSnapshotService {
|
||||
private final SiteSnapshotMapper snapshotMapper;
|
||||
private final SiteConfigMapper siteConfigMapper;
|
||||
private final SiteMapper siteMapper;
|
||||
private final ConfigService configService;
|
||||
private final SitePagesService sitePagesService;
|
||||
private final RiskRuleMapper riskRuleMapper;
|
||||
private final CachedStorageService storageService;
|
||||
@@ -52,7 +50,7 @@ public class SiteSnapshotServiceImpl implements SiteSnapshotService {
|
||||
String siteType = site != null && site.getSiteType() != null ? site.getSiteType().getValue() : null;
|
||||
|
||||
// 1. 脚本
|
||||
SiteConfig latest = configService.getLatestConfig(siteId);
|
||||
SiteConfig latest = siteConfigMapper.selectLatestBySiteId(siteId);
|
||||
if (latest != null && latest.getScriptStoragePath() != null && !latest.getScriptStoragePath().isBlank()) {
|
||||
try {
|
||||
String script = storageService.read(latest.getScriptStoragePath());
|
||||
|
||||
Reference in New Issue
Block a user