Evergreen 品牌 Logo

数据中枢 DataHub

数据谱仪器架构演示 · 并发拉取 / 登录域调度 / 失败重试 / 订阅刷新

← 架构总览 核心架构 T2 · data-hub
0数据源
0登录域
0重试次数上限
0退避间隔
0自动刷新刻度
堆栈全景 · 调度演示 循环演示
L4消费层 · Consumers
HTML 插件platform.data.get / refresh / subscribe
Renderer 看板allStatuses · fetchPaths · dataChangeEvents
Agent 工具getByName / streamByName
L3数据服务层 · DataHttpServer
REST 拉取GET /data/types/:name · POST …/refresh
状态与连通GET /data/status · POST /data/connectivity/test
SSE 订阅GET /data/stream/:name · GET /data/events
L2中枢核心层 · DataOrchestrator
数据中枢 DataOrchestrator
注册表register / unregister
两级缓存Cache · 磁盘 + 内存
状态与轨迹status · fetchPath
diff 变更通知DataChangeEvent
同域重试调度domainRetry
会话中心SessionCoordinator
L1数据源层 · 按登录域分组
zju.jwxt.edu.cn provider · zju
成绩单scores
课程表courses
考试安排exams
github.com 未注册 provider
GitHub Starsgithub_stars
Releasesgithub_releases
本地 · 无登录域 不介入重试
插件存储plugin_storage
PHASE 01 初始化调度演示 …
schedulingSnapshot { … }
同域后台重试 · 退避 2s · 上限 3 次
1第 1 次
2第 2 次
3第 3 次
待命

演示为示意循环;prefers-reduced-motion 下自动静止为终态。

💡 机制对照:本演示对应 evg-base/lib/core/data/orchestrator.dart —— refreshAllStale(过期源并发)→ _scheduleDomainRetry(按登录域登记)→ _runDomainRetries(有 provider 的域域内并发 / 无 provider 的域域内串行)→ _retryOne(退避 2s · 上限 3 次 · 达上限保留 lastError)。
核心机制 6 项
失败重试 · 退避调度
domainRetryDelay · _scheduleDomainRetry
  • 拉取失败立即返回,不堵塞调用方 / 启动期并行拉取
  • 按 name 去重登记进后台队列,启动 2s Timer
  • 后台 Timer 中执行;单源失败只记录,不阻塞同域其他源
关键
次数上限 · 防无限循环
domainRetryMaxAttempts · _retryOne
  • 每源独立计数(_domainRetryAttempts),默认 3 次可配置
  • 未达上限 → 重新入队,等待下一个周期再试;达上限 → 放弃
  • ≤0 完全禁用后台重试;_domainRetryRunning 防重入
关键
最终状态 · 降级语义
DataSourceStatus · 契约⑤
  • 成功 → 覆写磁盘+内存缓存 · connected=true
  • 重试耗尽 → connected=false · lastError 保留(真实失败)
  • 有真实旧缓存 → 仅警告「已展示缓存数据」,永不硬报错
  • 空数据门控:空结果视为失败,旧缓存保持可用
状态
订阅刷新 · 时钟对齐
startAutoRefresh · refreshAllStale
  • 默认 5 分钟刻度(:00/:05/:10…),首 tick 对齐不立即执行
  • 过期源并发刷新(Future.wait),单源失败不拖垮整批
  • 报错 ≠ 终态:每个 tick 都会再次尝试失败源,直至成功或注销
周期
变更通知 · diff
DataChangeEvent · data_diff
  • 后台刷新覆写缓存且内容实质变化 → 广播变更事件
  • 忽略易变字段(ts / timestamp / updatedAt …);首次拉取与空数据不发
  • 消费方:addDataChangeListener / dataChangeEvents / SSE /data/events
事件
缓存与取数链
get · fastRead · Cache · 会话重登
  • 缓存优先:磁盘 → 内存 → 拉取;过期也返回;fastRead 零 I/O
  • 静态兜底 fallback:失败且无旧缓存时返回预设值
  • 会话失效:SessionCoordinator 单点重登 → 重拉一次(登录锁分组)
链路
单次拉取阶段链 · fetchPath T2e 轨迹
01queued
→
02cacheLookup
→
03fetching
→
04validating
→
05caching
→
06done
或
✕failed
成功链 / 失败链循环演示 …
🔁 分支路径:会话失效且注册 provider → refreshSessionFor 单点重登 → 重新进入 fetching 重拉一次; 失败无缓存 → failed 后登记同域后台重试,回到 fetching 周期重试(轨迹 isActive=true · retryCount 累计)。