Skip to content

重构路线图 ​

重构设计阶段已收口:Phase 0-4 已落地;Phase 5 的可选能力按模块和实现边界分别核对。运维 HTTP/console/profile 功能已有实现,但当前由 shield_bootstrap 承载,shield_ops CMake target 仍为空壳,因此不能将 shield_ops 模块本身标为已落地。旧文档中“Phase 1-7 全部完成”的口径对应更早一代架构,与本路线图的 refactor 范围不同。

说明:以下勾选表示对应源码路径已经进入当前 refactor 验证范围;文档边界冻结但源码仍未完成的事项保持未勾选。

当前收敛目标是先关闭一个可验证的单节点最小闭环:shield::run、Phase 1 配置验证、Lua module-table service、local registry、基础 send/call 返回形态、TCP gateway 边界、插件系统 v1 的 manifest/instance/binding 主路径和缺失插件能力的明确错误。handler 内 coroutine-aware call/sleep 已进入当前实现路径;任何需要多节点、真实后端、timer/fork coroutine 化、UDP/KCP/WebSocket 或官方可选模块的能力都不能作为当前 Phase 1 阻塞项。

设计决策记录集中在 Decision Log;架构层面决策集中在 架构决策记录。如果后续新增开放问题,需要先记录,再同步更新对应权威文档和本路线图。

架构纠偏(ADR 驱动) ​

以下顺序源于 架构决策记录。每一步必须独立验收;旧实现只能作为待删除源码存在,不能继续出现在 public 文档、示例或测试目标中。

  1. [x] CAF 调度地基:dispatch 上下文为 thread-local(tls_dispatch_stack),Service registry 由 shared_mutex 保护;不改变 public 语义。
  2. [x] CAF Service runtime 闭环:Lua Service 的 spawn、mailbox、send、call、exit 全部落到 CAF actor;legacy Mailbox / worker thread / pump_once / 同步调用 fallback 已删除,LuaServiceManager 构造时必须绑定 caf::actor_system。
  3. [x] Service call 语义:使用 CAF request/reply 驱动 Lua coroutine yield/resume,禁止跨 VM 同步重入。(M4:统一 call_session 协程路径 + C++ 外部等待者;timer/fork 回调协程化;SyncCallMessage 与 CV 阻塞已删除)
  4. [x] 客户端内部消息类别:CAF behavior 接入结构化 ClientIngress、ClientEgress 与 client lifecycle control,禁止把所有 envelope 压成字符串或普通 Lua method。(M2/M3)
  5. [x] RPC descriptor 与 binding:compiled descriptor 定义 route_id, name, direction, binding, request_schema, request_codec(schema_id / response_schema / binding_hint 已移除:schema 寻址收敛为「路由名同名约定 + request_schema 显式覆盖」,配置出现即报错);每个目标 VM 启动时编译 route_id -> cached Lua handler,缺失或重复 binding 直接启动失败。(M1:actors[].rpc.routes 为唯一静态来源,network.protocol.routes 出现即报错)
  6. [x] Session 绑定:Gateway 维护 session 绑定(target ServiceHandle、player_id、epoch、protocol profile)。认证前 target = AuthService,认证后原子切换 target = PlayerService。room/scene/map 动态路由由 PlayerService 私有状态管理。(M2:SessionBinding CAS apply_binding,epoch 递增使旧引用失效)
  7. [x] 入站路径:Gateway 只读 header route_id,经轻量路由表校验后投递 ClientIngress 到 session.target;目标 actor 命中 handler 后按 RPC schema 解 body。删除 Gateway 提前 decode、Lua 通用客户端回调和二次 route dispatch。(M3:on_client_message JSON 压平回调与 body 藏 route 分支已删除)
  8. [x] 出站注册方法:生成的 server-to-client RPC helper 构造 ClientEgress;Gateway 校验 session 后把 route_id 写入 header。删除通用 session 发送和 route/payload envelope。(M2/M6:shield.client_rpc.<name> helper;header-route envelope(idlen/typelen)下 json body 为纯业务数据,不再写 {route, route_id, payload} 包装)
  9. [x] Route direction 与安全校验:冻结并实现 ClientToServer / ServerToClient,校验预登录权限、认证状态、body schema 与 stale epoch。(direction/requires_auth/stale epoch 已实现并测试;body schema 按冻结口径收敛为 descriptor 元数据记录,物理校验随 schema 工具链后置)
  10. [x] 多 worker 调度:由 CAF scheduler 并行执行不同 Service actor,保持单 Service/Lua VM 同时只有一个执行者。(M1 起 service 即 CAF actor,shutdown_all 的结构化退出保持预算内单执行者语义)
  11. [x] 死代码与旧测试清理:删除旧 Gateway bridge/legacy frame 客户端业务入口,以及无调用方的 transport codec/encryption 残留;测试矩阵只验收新契约。

客户端 RPC 闭环验收 ​

  • wire body 中只有纯业务数据;唯一运行时路由键是 header route_id。(已由 tests/acceptance/test_client_rpc_e2e.cpp 在真实 TCP 链路上验证:idlen 帧头 route_id、login → bind → move → s2c 回包、body 无路由字段)
  • 所有客户端消息经 Gateway 发给 session.target(登录前 → AuthService,登录后 → PlayerService)。
  • Gateway 不从 route_id 解析目标服务,不做多目标路由。
  • 目标服务转发给 room/scene/map 由 Lua 内部决定。
  • Gateway 在选择目标前不解普通 RPC body。
  • 目标 VM 不做字符串反射或 Lua if/else route dispatch。
  • handler 收到可信 player/client context 和该 RPC 的业务参数,不收到 transport 元数据。
  • response/push 只通过注册的 server RPC helper 发出,旧 epoch 无法写入新连接。

Phase 0: 文档和边界冻结 ​

  • [x] 统一所有文档为单节点优先、Lua-first 运行时口径。
  • [x] 明确 core 非目标:discovery、metrics、health、plugin、DI/IoC、annotations、conditions、events、middleware chain、重 ORM / XML mapper codegen。
  • [x] 明确 shield_cluster 是官方可选模块,不进入 shield_core,但保留地址、超时和错误语义。
  • [x] 区分目标 API、当前实现、旧架构遗留模块。
  • [x] 以 docs/lua-api.md 冻结 Lua API 契约。
  • [x] 以 docs/lua-api-tests.md 冻结 Lua API 测试矩阵。
  • [x] 以 docs/cmake-refactor.md 冻结 CMake target 拆分方向。

Phase 1: 运行时目录重排 ​

  • [x] 保留 actor、net、transport、script、timer、config、log、plugin。语义归属:actor 由 shield_core 承载,script/timer 由 shield_lua + shield_core 协作,后端能力由 shield_plugin 和独立插件承载。
  • [x] 将当前 protocol/ 逐文件分类:字节流 framing/codec/encryption 进入 shield_transport,客户端 session 相关能力进入 shield_net,schema protocol 进入 deferred tooling。shield/protocol/* 与 shield/transport/protocol/* 残留 header 与对应源文件、测试已在本次清理中删除。
  • [x] 处理 gateway/:gateway 收敛为 Lua service pattern;C++ gateway 残留代码与对应测试已删除。
  • [x] 废弃 raw shield_data 模块方向;数据访问收敛为插件系统 v1 + include/shield/plugin/* C ABI + 独立 provider 插件。
  • [x] 删除或移出 discovery、旧 core metrics、旧 core health、di、annotations、conditions、events、旧插件 v0。对应源码、headers 与测试已一并清除;shield_extensions target 不再存在。
  • [x] 决定物理目录策略:短期保留当前目录,用 CMake target 和 include 边界先收敛;不在 Phase 1 做大规模机械搬迁。

Phase 2: Lua API 契约 ​

  • [x] 实现 Lua service module table loader 和 on_init(args) 最小调用路径。
  • [x] 从 actors 配置启动 Lua service 实例。
  • [x] 实现 shield.spawn / shield.exit 的单节点最小路径。
  • [x] 实现 opaque ServiceHandle、name reserve/publish 状态和 coroutine-aware spawn。
  • [x] 实现 shield.query/register/unregister/names 的单节点最小 registry 路径。
  • [x] 提供 shield.now。
  • [x] 实现 timer_once/timer/cancel_timer、handler 内 coroutine-aware sleep、fork task id。
    • timer_once/timer/cancel_timer 已走 CAF actor timer,callback 通过 service actor 调度并以 invoke_coroutine 协程方式执行(可 shield.sleep/shield.call 挂起,不阻塞 actor),错误路由到 on_error hook。
    • fork 已走 CAF actor 调度(enqueue_forked_task + fork_task_atom),task body 以 invoke_coroutine 协程方式执行(raw_fn 有效时),错误路由到 on_error hook。
    • shield.sleep 已实现 handler 协程感知:async handler 中 yield + 由 _resume_after 定时器 resume;非协程路径走 _block_sleep 阻塞。LAPI-007-08/09/10 已覆盖。
    • shield.call / shield.call_timeout 已实现统一协程调用路径(_coro_call → suspend_for_call + coroutine.yield() → caller actor mailbox 回投 → resume_caller);主线程/module-level 调用返回 call_not_allowed_off_coroutine,C++ manager.call() 走外部等待者(同一 call_session 协议)。call timeout 由 CAF delayed call_timeout_atom 驱动。LAPI-005 已覆盖。
  • [x] 提供 shield.log.*。
  • [x] 删除旧 shield.db.* / shield.redis.* 全局数据 API,数据访问统一走插件 namespace + binding 逻辑名。
  • [x] 插件系统 v1 提供 manifest scan、catalog、instance、binding、C ABI guard、register_lua 分发和只读 introspection。
  • [x] 迁移官方数据插件的 Lua callable namespace:shield.database.* / shield.cache.redis / shield.queue.redis / shield.leaderboard.redis 均接收 binding 而非 instance_id。
  • [x] Lua 层 mapper/helper 只能作为插件 proxy 上的辅助能力存在;XML schema-mapper parser / descriptor / codegen 仍属 deferred 设计,不进入当前最小 runtime。
  • [x] 实现 shield.call 挂起当前 Lua 协程但不阻塞 CAF scheduler 线程的语义。shield.call / shield.call_timeout 已实现协程感知调用路径(_coro_call → suspend_for_call → coroutine.yield() → resume_caller),call timeout 由 CAF delayed call_timeout_atom 驱动。LAPI-005-06 已覆盖协程 timeout 和同步调用两条路径。
  • [x] 删除旧 shield.service("name")、冒号式 DB/Redis API 和 legacy on_message(src, type, data) 入口。

Phase 3: C++ 入口和配置 ​

  • [x] 增加 include/shield/shield.hpp。
  • [x] 实现顶层 shield::run(argc, argv),包装或替代当前 shield::bootstrap::run(argc, argv)。
  • [x] 冻结 CLI 细节:--config 默认值/必填、多配置文件、--node-id 归属、legacy subcommand 去留、退出码。
  • [x] 明确 actors、network、plugins、log 的最小 schema。
  • [x] 实现启动期最小配置验证:optional 配置段未启用即失败、Phase 1 deferred transport 拒绝启动、actor/plugin 基础字段校验。
  • [x] 为 shield 可执行文件增加 CLI/config smoke tests。
  • [x] 移除旧 CLI 文档与新入口冲突。

Phase 4: 示例和测试 ​

  • [x] 让 examples/hello_world/ 接入统一 shield::run 入口。
  • [x] 验证 examples/hello_world/ 可构建启动。构建由 examples/CMakeLists.txt 注册;启动验收由 test_hello_world_acceptance 在构建产物上检查 shield::run 入口、配置文件与 Lua 脚本契约。运行时端到端 smoke 由 shield_runtime_lua_smoke / shield_runtime_registry_smoke / shield_runtime_data_smoke 在 shield --check-config 路径上覆盖。
  • [x] 补齐 examples/hello_world/ 的 Lua 业务消息验收。acceptance test 已覆盖 echo.lua 的 sender/send/log/now、gateway.lua 的 connect/disconnect/client_message、player.lua 的 login/chat/logout/self/exit 和插件 namespace API 模式。
  • [x] 增加最小 Lua API runtime smoke test。
  • [x] 增加本地 registry runtime smoke test。
  • [x] 按 LAPI 矩阵补齐当前 Lua API 绑定测试;当前 tests/lua_api/ 覆盖 lifecycle、timers、registry、messaging、call、context、legacy、config 和 gateway。插件 Lua API 由插件系统和各 provider 测试继续补齐。
  • [x] 按 docs/lua-api-tests.md 补齐独立 API 用例,示例不替代测试。
  • [x] 为新 public/core 头增加 CAF 泄漏静态检查。
  • [x] 收敛 legacy public headers 的 CAF 泄漏并纳入检查。
  • [x] 为 shield_core forbidden module include 增加静态检查。

当前模块核对快照 ​

模块当前状态核对结论
shield_base当前 CMake target 已存在基础类型路径已收敛;单元测试已补齐(test_cov_base_id 覆盖 id,test_cov_base_types 覆盖 byte_buffer/error/result/time,顺带修正 ByteBuffer::clear 不重置读位置的疏漏)
shield_core当前 CMake target 已存在已收敛为 CAF 消息契约(service_message.hpp)+ CAF 类型注册;无人使用的 CafAdapter/ServiceRegistry/MessageEnvelope 平行层已删除,registry/handle 语义由 shield_lua 的 LuaServiceManager 承载
shield_config当前 CMake target 已存在Phase 1 启动期验证已接入;旧 ConfigManager/动态配置测试已从当前构建入口移出
shield_log当前 CMake target 已存在logger facade 已接入;旧 Boost log config 测试已从当前构建入口移出
shield_transport当前 CMake target 已存在协议管线 + RPC descriptor 表;旧 frame/codec/encryption 与对应测试已删除,TCP 无 network.protocol 为启动错误
shield_net当前 CMake target 已存在单实例 TCP listener/session 已接入 bootstrap 的 actors[].network.tcp;UDP/WebSocket 仍为 deferred
shield_plugin当前 CMake target 已存在插件系统 v1 已接入 manifest、instance、binding、C ABI、Lua register_lua 和官方数据插件;host 不链接 DB/Redis 驱动,不存在 shield_data target
shield_lua当前 CMake target 已存在module table/on_init/spawn/registry/基础 API 已接入;coroutine-aware sleep/call/timeout/spawn 已实现(异步 spawn 由专用 worker 线程执行 on_init,含 name reserve/publish 与超时补偿退出);shield.panic 已接入 on_panic + exit("panic");on_error/on_panic/on_exit guard 已实现;客户端 RPC 已接入 typed ClientIngress/ClientEgress 与只读 ClientContext/ClientRef userdata(shield.client.bind/close + shield.client_rpc.<name> helper),shutdown_all 支持预算内结构化退出与超时强杀
shield_bootstrap当前 CMake target 已存在shield::run 和 CLI/config smoke tests 已登记在主 CMake
optional modulesCMake 开关存在,默认关闭shield_cluster M1-M5 已落地:心跳调度、CAF middleman transport(握手/保活/重连)、路由学习(心跳捎带广播)、跨节点 node:service send/call 投递与观测指标(详见 runtime-cluster.md)。shield_player P0 已落地:shield.player.setup 状态机、多设备裁决、重连窗口、离线推送队列与持久化约定(详见 runtime-player.md);P2 已落地 shield.player.Base 语法糖(OD-014:基于 setup 的按名收集,无第二套 lifecycle/继承);远端 resolve 留 Phase 2+。shield_server P0 已落地:状态机(starting/running/maintenance/shutdown)、维护模式、shutdown(ms) 关闭交接、watch 状态通知与 ops 只读快照(详见 runtime-server.md)。shield_global P0 已落地:shield.global()(KV + 本地缓存)、互斥/读写/自旋/分布式锁门面(P0 与本地后端共享进程内 GlobalManager)、shield.rank() 排行榜、普通/延迟/可靠队列、shield.scheduler()(cron/interval/once + pause/resume/remove/trigger)、shield.rate_limiter()(allow/remaining/wait,token_bucket + sliding_window 进程内实现,Redis 周期同步留 Phase 2+)、shield.priority_queue()(push/pop/length/purge,值越小越优先、同优先级 FIFO,进程内实现)、shield.broadcast_queue()(subscribe/unsubscribe 回调分发 + 有界 history/每组 cursor 离线补发,进程内实现);跨进程 Pub/Sub 与 Redis 后端留 Phase 2+(详见 runtime-global.md)。shield_ops P0 已起步:轻量 /ops/health 探针(进程内读取、不经 Lua actor 往返,checks 含 core/plugins 与按需 server/cluster/global)、/ops/metrics Prometheus 0.0.4 导出(shield_uptime_seconds、插件/服务/队列/锁/排行/调度/集群传输族,含 per-service 流量计数 shield_service_requests_total/shield_service_errors_total)与 /ops/services/:name 服务详情(registry 只读快照含流量/uptime/timers/pending_calls/pending_tasks/coroutines/memory_kb 统计,404/504 语义与列表一致);health verdict 映射 HTTP 状态码(degraded → 503);诊断控制台两层架构(root.* + attach/eval)已实现,ops-lua-console.md 状态声明已按 L1/L2/L3 分层核对修正,L1 只读快照已全量落地(coroutines 协程埋点 + memory_kb dispatch 退出采样),L2 受限 inspect 已全量落地(lua.inspect summary/timers/pending_calls 只读投影 + memory owner 线程 GC 采样与 retainers 摘要 + coroutines owner 线程 live 协程枚举与 resume 记账 + refs owner 线程对象图遍历 + lua.snapshot/lua.diff 快照对比,snapshot 支持 refs 参数附带对象图摘要与 diff 按 path 匹配的 refs delta);/ops/profile 已提供(采样式 CPU 热点分析 + 慢调用追踪,sticky 阈值门 http.slow_call_threshold_ms,report 与采样会话解耦;详见 runtime-ops.md 的 Profile 小节)

Phase 5: 官方可选模块 ​

以下内容不属于当前 refactor core,但属于官方可选模块或扩展方向。Cluster、global、player、server 的已实现范围见上文快照与 runtime-*.md;Ops 的运维功能部分已实现并由 bootstrap 承载,但 shield_ops target 为空,配置 owner ops: 也尚未接入。下列条目保留原设计并标明实际边界:

  • shield_cluster:多进程/多机器通信、节点心跳、远端路由 cache、可选服务发现。
  • shield_global:跨进程数据、分布式锁、排行榜、队列、限流器。
  • shield_player:玩家 setup、PlayerRef、PlayerManager、重连、持久化 adapter。
  • shield_server:服务器状态、维护模式、关闭广播、运行时信息。
  • shield_ops:Prometheus 指标、健康检查、HTTP/console 管理端点、profile。(P0 已落地 /ops/health(verdict 映射 503)+ /ops/metrics + /ops/services/:name 含 per-service 流量/uptime/timers/pending_calls/pending_tasks/coroutines/memory_kb 统计(L1 全量)+ console 侧 L2 受限 inspect 全量(lua.inspect summary/memory/coroutines/timers/pending_calls/refs + lua.snapshot/lua.diff,snapshot refs 参数附对象图摘要);/ops/profile 已提供(采样式 CPU 热点分析 + 慢调用追踪;详见 runtime-ops.md 的 Profile 小节),消息延迟剖面另行立项评估)
  • [x] 冻结每个 optional module 的初始化失败策略:默认 fail fast;shield_cluster 允许远端连接失败时退化为单节点 unhealthy;未启用却配置 optional 段必须启动失败。
  • [x] 冻结 shield_player 文档契约:shield.player.setup 主 API 与默认 hook 实现表、persistence adapter 边界、PlayerRef 本地/远端边界、anonymous/spectator opt-in 状态、多设备策略、player_pool 容量模型和 shield.player.Base 语法糖边界。实现仍按 P0/P1/P2 分阶段推进。
  • [x] 落地 shield_server P0:进程级 ServerManager 单例、四态状态机与迁移校验、shield.server Lua 门面(state/set_state/shutdown/watch)、shutdown(ms) 经 request_stop 的关闭交接、/ops/status server 块与 root.server 只读快照(OD-016/OD-017)。
  • [x] 落地 shield_server P1:外部停机(SIGINT/SIGTERM 等)由 bootstrap 在 shutdown 入口统一把 ServerManager 迁移到 shutdown 态并投递观察者通知(外部停机不承诺 Lua 观察窗口)。

插件系统 ​

详见 插件系统设计文档。

当前插件系统按 v1 重新设计,不兼容旧实验实现。旧的 PluginManager、plugins.enabled、shield_plugin_api()、shield_plugin_type、全局 find_plugin 和 shield_redis 基础设施插件口径不再作为完成状态。

  • [x] 冻结 v1 文档方向:metadata-first、外部 YAML manifest、发现/加载/启动分离、package/instance/binding 模型。
  • [x] 实现 manifest 扫描和 catalog 构建。
  • [x] 实现 plugins.instances、plugins.bindings 和依赖解析。
  • [x] 实现 shield_plugin_get_v1() ABI 入口和二进制 guard。
  • [x] 实现配置 schema 校验和默认值合并。
  • [x] 实现结构化错误对象和加载阶段错误报告。
  • [x] 实现 Lua introspection:packages、instances、instance、binding。
  • [x] 迁移 DATABASE / CACHE / QUEUE / LEADERBOARD / METRIC / HEALTH / MATCHMAKING 等 provider 到 interface-based v1(含 sqlite/mysql/postgresql/mongodb/redis 系/queue/leaderboard/metrics.prometheus/health.http/matchmaking.elo)。认证/JWT 不作为 Shield 官方插件发布,保留在业务层实现。
  • [x] 决策:v1 不支持热加载、沙箱、请求级生命周期;这些方向不进入 v1,未来如需引入须重新设计 ABI 版本。

Later ​

以下内容不属于当前 refactor core,也不属于已冻结的官方模块契约:

  • 高级数据 mapper。
  • Schema 工具链。
  • Lua runtime primitives / cosocket 风格出站 I/O(如 shield.buffer / shield.socket / shield.stream / shield.tls)。
  • shield.crypto 一期切片已落地(2026-09-28,AD-08:编解码 / SHA-256 / HMAC-SHA256 / random_bytes / constant_time_compare),作为业务层自建认证的原语基础; 二期四刀(KDF → 对称加密 → 非对称 → JWKS)已全部落地(2026-10-09): PBKDF2/HKDF、AES-256-GCM、Ed25519、JWT EdDSA + JWKS(scripts/lib/jwt.lua)。

说明:

  • 当前主路径不要求用户理解或使用上述 primitives。
  • 当前推荐心智模型仍然是:客户端入站走 gateway 单一 target + ClientContext/shield.client_rpc.<name> helper,服务间走 shield.send/call,对外 HTTP 走 shield.http。
  • primitives / cosocket 方向只保留为后置草案,不作为当前阶段阻塞项。

Apache License 2.0