feat: 日志持久化(6h归档) + purge增强(source_type/source_has_status过滤)

- ActivityRecorder 新增 LogPersister 后台线程,每10s增量写入logs/operations.*.log

- 日志每6小时自动gzip压缩归档

- memory_purge 新增 source_type / target_type / source_has_status 过滤条件

- 支持精准清理已归档任务的残留 HAS_STATE 关系
This commit is contained in:
root
2026-04-30 08:36:02 +08:00
parent 6749811e49
commit c046e6ff6a
7 changed files with 404 additions and 53 deletions

View File

@ -913,7 +913,11 @@ function init() {
positions[node.id] = { x, y, z };
});
// 简单力导向模拟(迭代几次)
// 简单力导向模拟(迭代几次)— 使用度数加权距离
function getIdealDist(id) {
return 5 + ((nodeDegrees[id] || 0) * 0.8);
}
for (let iter = 0; iter < 30; iter++) {
// 斥力:节点之间互相排斥
Object.keys(positions).forEach(id1 => {
@ -926,8 +930,14 @@ function init() {
const dz = pos1.z - pos2.z;
const dist = Math.sqrt(dx*dx + dy*dy + dz*dz) + 0.1;
if (dist < 10) {
const force = 0.04 / Math.max(dist, 0.5);
// 动态阈值:度数越高理想距离越大,取两节点较大值
const idealDist = getIdealDist(id1) + getIdealDist(id2);
const repulsionThreshold = idealDist * 1.5;
if (dist < repulsionThreshold) {
// 斥力强度按度数加权
const degreeWeight = ((nodeDegrees[id1] || 0) + (nodeDegrees[id2] || 0)) * 0.5 + 1;
const force = (0.04 * degreeWeight) / Math.max(dist, 0.5);
const fx = (dx / dist) * force;
const fy = (dy / dist) * force;
const fz = (dz / dist) * force;
@ -953,7 +963,11 @@ function init() {
const dz = pos2.z - pos1.z;
const dist = Math.sqrt(dx*dx + dy*dy + dz*dz) + 0.1;
if (dist > 15) {
// 动态引力阈值:以两节点平均理想距离为基准
const idealDist = (getIdealDist(edge.source) + getIdealDist(edge.target)) * 0.8;
const attractionThreshold = idealDist * 1.5;
if (dist > attractionThreshold) {
const force = 0.05;
const fx = (dx / dist) * force;
const fy = (dy / dist) * force;
@ -1236,6 +1250,18 @@ function smoothReposition() {
};
});
// 重新计算度数(从当前节点 + 边)
const smoothDegrees = {};
nodeMeshes.forEach(m => { smoothDegrees[m.userData.nodeId] = 0; });
edges.forEach(e => {
smoothDegrees[e.source] = (smoothDegrees[e.source] || 0) + 1;
smoothDegrees[e.target] = (smoothDegrees[e.target] || 0) + 1;
});
function getSmoothIdealDist(id) {
return 5 + ((smoothDegrees[id] || 0) * 0.8);
}
// 用力导向模拟迭代 30 次平滑
for (let iter = 0; iter < 30; iter++) {
// 斥力
@ -1248,8 +1274,11 @@ function smoothReposition() {
const dy = a.y - b.y;
const dz = a.z - b.z;
const dist = Math.sqrt(dx*dx + dy*dy + dz*dz) + 0.1;
if (dist < 12) {
const force = 0.08 / Math.max(dist, 0.5);
const idealDist = getSmoothIdealDist(ids[i]) + getSmoothIdealDist(ids[j]);
const repulsionThreshold = idealDist * 1.5;
if (dist < repulsionThreshold) {
const degreeWeight = ((smoothDegrees[ids[i]] || 0) + (smoothDegrees[ids[j]] || 0)) * 0.5 + 1;
const force = (0.08 * degreeWeight) / Math.max(dist, 0.5);
a.x += (dx/dist) * force;
a.y += (dy/dist) * force;
a.z += (dz/dist) * force;
@ -1268,7 +1297,9 @@ function smoothReposition() {
const dy = p2.y - p1.y;
const dz = p2.z - p1.z;
const dist = Math.sqrt(dx*dx + dy*dy + dz*dz) + 0.1;
if (dist > 8) {
const idealDist = (getSmoothIdealDist(e.source) + getSmoothIdealDist(e.target)) * 0.8;
const attractionThreshold = idealDist * 1.5;
if (dist > attractionThreshold) {
const force = 0.03;
p1.x += (dx/dist) * force;
p1.y += (dy/dist) * force;