From b985e6140e7f395ead7dc55e41e6b16d97f9f02b Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期日, 30 八月 2026 14:44:30 +0800
Subject: [PATCH] 简化开发模拟器历史数据管理
---
ruoyi-device/src/main/java/com/ruoyi/device/bts/BtsDevelopmentSimulator.java | 1
ruoyi-device/src/main/java/com/ruoyi/device/simulator/InMemoryBtsSimulatorStateStore.java | 9 +++-
ruoyi-admin/src/main/java/com/ruoyi/config/RedisBtsSimulatorStateStore.java | 24 ++++++++++++
ruoyi-device/src/main/java/com/ruoyi/device/simulator/BtsSimulatorStateStore.java | 5 ++
ruoyi-admin/src/test/java/com/ruoyi/config/RedisStateStoreTest.java | 11 +++--
ruoyi-device/src/main/java/com/ruoyi/device/simulator/DevelopmentCollectorSimulation.java | 3 +
ruoyi-device/src/test/java/com/ruoyi/device/contract/SimulatorPublicContractTest.java | 8 ++--
7 files changed, 49 insertions(+), 12 deletions(-)
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/config/RedisBtsSimulatorStateStore.java b/ruoyi-admin/src/main/java/com/ruoyi/config/RedisBtsSimulatorStateStore.java
index f151ea6..796c15e 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/config/RedisBtsSimulatorStateStore.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/config/RedisBtsSimulatorStateStore.java
@@ -47,6 +47,29 @@
return restoreState(stored);
}
+ @Override
+ public SimulatorState resetHistoryForDemoStartup(SimulatorState state)
+ {
+ pendingEmbeddedHistory = List.of();
+ Set<Object> historyKeys = redisTemplate.opsForSet().members(HISTORY_KEYS_KEY);
+ if (historyKeys != null && !historyKeys.isEmpty()) redisTemplate.delete(historyKeys);
+ redisTemplate.delete(HISTORY_KEYS_KEY);
+
+ List<com.ruoyi.device.simulator.BtsSimulatorStateStore.CollectorState> collectors = state.collectors()
+ .stream()
+ .map(collector -> new com.ruoyi.device.simulator.BtsSimulatorStateStore.CollectorState(
+ collector.collectorId(), collector.deviceCode(), collector.ip(), collector.mac(),
+ collector.name(), collector.manufacturer(), collector.model(), collector.channelCount(),
+ collector.online(), collector.sampleIntervalMs(), 1L,
+ null, collector.channels(), List.of(), 0L,
+ collector.historyFaults()))
+ .toList();
+ SimulatorState reset = new SimulatorState(state.version(), state.devices(), collectors,
+ state.nextDeviceId(), state.nextCollectorId(), state.tombstones());
+ redisTemplate.opsForValue().set(STATE_KEY, JSON.toJSONString(reset));
+ return reset;
+ }
+
private SimulatorState restoreState(Object stored)
{
ParsedSimulatorState parsed = parseState(stored);
@@ -88,6 +111,7 @@
List<Object> records = new ArrayList<>(
append.records().stream().map(JSON::toJSONString).toList());
typed.opsForList().rightPushAll(historyKey, records);
+ typed.opsForList().trim(historyKey, -MAX_HISTORY_RECORDS, -1);
typed.opsForSet().add(HISTORY_KEYS_KEY, historyKey);
}
}
diff --git a/ruoyi-admin/src/test/java/com/ruoyi/config/RedisStateStoreTest.java b/ruoyi-admin/src/test/java/com/ruoyi/config/RedisStateStoreTest.java
index dc22f33..41523d4 100644
--- a/ruoyi-admin/src/test/java/com/ruoyi/config/RedisStateStoreTest.java
+++ b/ruoyi-admin/src/test/java/com/ruoyi/config/RedisStateStoreTest.java
@@ -125,7 +125,7 @@
}
@Test
- void doesNotOverwriteDamagedEmbeddedHistoryBeforeValidation()
+ void clearsLegacyEmbeddedHistoryForDemoStartup() throws Exception
{
AtomicReference<Object> stored = new AtomicReference<>("{\"version\":1,\"devices\":[],"
+ "\"collectors\":[{\"collectorId\":1,\"deviceCode\":\"dev-sim-collector-1\","
@@ -145,10 +145,11 @@
+ "\"historyFaults\":{\"missingSequences\":[],\"outOfOrder\":false}}],"
+ "\"nextDeviceId\":1,\"nextCollectorId\":2,\"tombstones\":[]}");
- assertThrows(IllegalStateException.class,
- () -> new BtsDevelopmentSimulator(0, store(stored)));
-
- assertEquals(true, stored.get().toString().contains("\"history\":[{"));
+ try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0, store(stored)))
+ {
+ assertEquals(0L, simulator.snapshot().collectors().get(0).historyRecordCount());
+ }
+ assertEquals(false, stored.get().toString().contains("\"history\":[{"));
}
@Test
diff --git a/ruoyi-device/src/main/java/com/ruoyi/device/bts/BtsDevelopmentSimulator.java b/ruoyi-device/src/main/java/com/ruoyi/device/bts/BtsDevelopmentSimulator.java
index 1af43b7..e66c092 100644
--- a/ruoyi-device/src/main/java/com/ruoyi/device/bts/BtsDevelopmentSimulator.java
+++ b/ruoyi-device/src/main/java/com/ruoyi/device/bts/BtsDevelopmentSimulator.java
@@ -62,6 +62,7 @@
{
this.stateStore = stateStore;
state = stateStore.loadOrInitialize(defaultState());
+ state = stateStore.resetHistoryForDemoStartup(state);
validateRestoredState();
stateStore.completeValidatedRestore(state);
simulator = ScriptedBtsTcpSimulator.responding(port, this::respond);
diff --git a/ruoyi-device/src/main/java/com/ruoyi/device/simulator/BtsSimulatorStateStore.java b/ruoyi-device/src/main/java/com/ruoyi/device/simulator/BtsSimulatorStateStore.java
index a950af0..0b03501 100644
--- a/ruoyi-device/src/main/java/com/ruoyi/device/simulator/BtsSimulatorStateStore.java
+++ b/ruoyi-device/src/main/java/com/ruoyi/device/simulator/BtsSimulatorStateStore.java
@@ -10,10 +10,15 @@
{
int CURRENT_VERSION = 1;
int MAX_HISTORY_BATCH_SIZE = 1000;
+ /** 开发演示只保留有限历史,避免 Redis 随运行时间无限增长。 */
+ long MAX_HISTORY_RECORDS = 20_000L;
/** 读取已有状态;仅在状态不存在时原子写入并返回默认状态。 */
SimulatorState loadOrInitialize(SimulatorState defaultState);
+ /** 开发模拟器启动时清理上一轮演示历史;正式业务存储不需要实现该动作。 */
+ default SimulatorState resetHistoryForDemoStartup(SimulatorState state) { return state; }
+
/** 完整保存下一版模拟器状态。 */
void save(SimulatorState state);
diff --git a/ruoyi-device/src/main/java/com/ruoyi/device/simulator/DevelopmentCollectorSimulation.java b/ruoyi-device/src/main/java/com/ruoyi/device/simulator/DevelopmentCollectorSimulation.java
index c0fb1fd..504a83b 100644
--- a/ruoyi-device/src/main/java/com/ruoyi/device/simulator/DevelopmentCollectorSimulation.java
+++ b/ruoyi-device/src/main/java/com/ruoyi/device/simulator/DevelopmentCollectorSimulation.java
@@ -131,7 +131,8 @@
CollectorState next = copy(current, current.ip(), current.channelCount(), current.online(),
current.sampleIntervalMs(),
sequence, lastSampledAt, current.channels(), List.copyOf(latest.values()),
- current.historyRecordCount() + appendedRecords.size(),
+ Math.min(BtsSimulatorStateStore.MAX_HISTORY_RECORDS,
+ current.historyRecordCount() + appendedRecords.size()),
current.historyFaults());
return new CollectorAdvance(next, appendedRecords);
}
diff --git a/ruoyi-device/src/main/java/com/ruoyi/device/simulator/InMemoryBtsSimulatorStateStore.java b/ruoyi-device/src/main/java/com/ruoyi/device/simulator/InMemoryBtsSimulatorStateStore.java
index 48e1263..2656282 100644
--- a/ruoyi-device/src/main/java/com/ruoyi/device/simulator/InMemoryBtsSimulatorStateStore.java
+++ b/ruoyi-device/src/main/java/com/ruoyi/device/simulator/InMemoryBtsSimulatorStateStore.java
@@ -41,8 +41,13 @@
public synchronized void save(SimulatorState state, List<CollectorHistoryAppend> historyAppends)
{
for (CollectorHistoryAppend append : historyAppends)
- collectorHistory.computeIfAbsent(append.collectorCode(), key -> new ArrayList<>())
- .addAll(append.records());
+ {
+ ArrayList<CollectorMeasurementRecord> history = collectorHistory.computeIfAbsent(
+ append.collectorCode(), key -> new ArrayList<>());
+ history.addAll(append.records());
+ int overflow = history.size() - (int) MAX_HISTORY_RECORDS;
+ if (overflow > 0) history.subList(0, overflow).clear();
+ }
this.state = state;
}
diff --git a/ruoyi-device/src/test/java/com/ruoyi/device/contract/SimulatorPublicContractTest.java b/ruoyi-device/src/test/java/com/ruoyi/device/contract/SimulatorPublicContractTest.java
index df11a42..c9f9697 100644
--- a/ruoyi-device/src/test/java/com/ruoyi/device/contract/SimulatorPublicContractTest.java
+++ b/ruoyi-device/src/test/java/com/ruoyi/device/contract/SimulatorPublicContractTest.java
@@ -158,7 +158,7 @@
}
@Test
- void collectorKeepsAppendOnlyHistoryBeyondPreviousDisplayLimit() throws Exception
+ void collectorKeepsOnlyBoundedDemoHistory() throws Exception
{
Instant startedAt = Instant.parse("2026-08-29T03:00:00Z");
TrackingHistoryStore store = new TrackingHistoryStore();
@@ -171,8 +171,8 @@
store.resetReadStats();
var page = simulator.collectorHistory(1, 0, 1);
- assertEquals(60_012, page.total());
- assertEquals(1, page.records().get(0).sequenceId());
+ assertEquals(BtsSimulatorStateStore.MAX_HISTORY_RECORDS, page.total());
+ assertTrue(page.records().get(0).sequenceId() > 1);
assertEquals(1, store.historyReads);
assertEquals(1, store.recordsRead);
}
@@ -182,7 +182,7 @@
{
assertTrue(store.historyReads > 1);
assertEquals(1000, store.maximumRequestedLimit);
- assertEquals(60_012, store.recordsRead);
+ assertEquals(BtsSimulatorStateStore.MAX_HISTORY_RECORDS, store.recordsRead);
}
}
--
Gitblit v1.7.1