附录 A aegis 卷一 API 与模块速查
卷一从第 1 章到第 17 章把 aegis 拆成十来个 internal 包,每章各写几段可编译、可 go test 的代码。本附录把全卷的导出面收成三类速查:模块地图回答「东西在哪」,按包 API 表回答「怎么调」,帧格式与命令号回答「线上长什么样」。表里每个签名都逐字取自对应节的 // file: 代码块,出处节号指向第一次给出它的那一节。
模块地图
aegis 每章一个独立 module,包路径相对该章 module 根。下表按依赖顺序排列。
| 包路径 | 职责 | 出处节 | 关键文件 |
|---|
internal/overview | 分层骨架与分工清单 | 1.1–1.3 | layers.go |
internal/netio | Reactor 循环与承载测量 | 2.1–2.3 | reactor_loop.go |
internal/proto | 帧头、分帧、版本协商 | 3.1–3.3 | header.go / frame.go |
internal/codec | 二进制读写、varint、零拷贝 | 4.1–4.3 | binary.go / zerocopy.go |
internal/kcp | 可靠 UDP 与弱网模拟 | 5.1–5.3 | kcp.go / hol.go |
internal/ws | 握手、分片、心跳、票据 | 6.1–6.3 | frame.go / server.go |
internal/session | 会话表、顶号迁移、网关 | 7.1–7.3 | table.go / gateway.go |
internal/router | 路由表、序号窗口、广播 | 8.1–8.3 | router.go / fanout.go |
internal/timing | 时间轮、冷却、世界时钟 | 9.1–9.3 | wheel.go / worldclock.go |
internal/actor | 邮箱、实体运行时、背压 | 10.1–10.3 | mailbox.go / entity.go |
internal/idem | 幂等窗口、指纹、结算 | 11.1–11.3 | window.go / reward.go |
internal/sync | 状态/帧同步、快照、AOI | 12.1–12.3 | world.go / snapshot.go |
internal/predict | 本地预测、和解、插值 | 13.1–13.3 | predict.go / interpolate.go |
internal/clock | 时间线、回滚、公平性 | 14.1–14.3 | clock.go / rewind/ / fairness/ |
internal/authority | 信任契约、移动校验、限速 | 15.1–15.3 | boundary.go / move.go |
internal/guard | 连接配额、封包加密 | 16.1–16.3 | limit.go / crypto.go |
internal/gateway + cmd/aegis | 进程装配与入口 | 17.1–17.3 | config.go / main.go |
internal/handoff + internal/review | 移交表与回顾台账 | 18.1 / 18.3 | handoff.go / ledger.go |
帧格式与命令号速查
全卷共用同一套 wire 契约,第 3 章定死、第 4 章起一律复用,不得自创。固定头 11 字节,length 统计它自身之后的字节数:
固定头(HeaderSize = 11)
length uint32 大端 bytes 0..3 length = 7 + N
cmd uint16 大端 bytes 4..5 命令号
seq uint32 大端 bytes 6..9 连接内自增序号
flags uint8 byte 10 标志位
载荷 N 字节 bytes 11..11+N
帧总长 = 11 + N MaxPayload = 1 << 20
命令号 type Cmd uint16,高字节是模块号(ModuleSystem 0x00 / ModulePlayer 0x01 / ModuleScene 0x02 / ModuleChat 0x03 / ModuleGuild 0x04 / ModuleMail 0x05),低字节是模块内序号。全卷实际用到的命令号如下(均出自 3.1 消息头与命令号
):
| 模块 | 符号 | 值 | 说明 |
|---|
| 系统 0x00 | CmdHeartbeatReq | 0x0001 | 客户端心跳 |
| 系统 0x00 | CmdHeartbeatResp | 0x0002 | 心跳应答 |
| 系统 0x00 | CmdErrorNotify | 0x0003 | 错误通知 |
| 系统 0x00 | CmdLoginReq | 0x0010 | 登录请求 |
| 系统 0x00 | CmdLoginResp | 0x0011 | 登录响应 |
| 世界 0x01 | CmdEnterWorldReq | 0x0101 | 进入世界 |
| 世界 0x01 | CmdEnterWorldResp | 0x0102 | 进入世界应答 |
| 世界 0x01 | CmdAttrSync | 0x0103 | 属性同步 |
| 场景 0x02 | CmdMoveReq | 0x0201 | 移动请求 |
| 场景 0x02 | CmdMoveResp | 0x0202 | 移动应答 |
| 场景 0x02 | CmdAoiAdd | 0x0203 | AOI 进入视野 |
| 场景 0x02 | CmdAoiRemove | 0x0204 | AOI 离开视野 |
| 聊天 0x03 | CmdChatSend | 0x0301 | 发送聊天 |
| 聊天 0x03 | CmdChatRecv | 0x0302 | 收到聊天 |
标志位 type Flags uint8:FlagRequest 1<<0 / FlagResponse 1<<1 / FlagPush 1<<2 / FlagCompressed 1<<3 / FlagEncrypted 1<<4 / FlagFragment 1<<5。
按包 API 速查
下表按包给出导出类型与关键方法,签名逐字取自对应节代码块;省略号表示字段较多,完整定义见出处节。
internal/proto(3.1–3.3)
| 符号 | 签名 | 说明 | 出处 |
|---|
Cmd / MakeCmd | type Cmd uint16 / func MakeCmd(module, sub uint8) Cmd | 命令号 | 3.1 |
HeaderSize / MaxPayload | const HeaderSize = 11 / const MaxPayload = 1 << 20 | 头长与上限 | 3.1 |
Header / PayloadLen | type Header struct { Length uint32; Cmd Cmd; Seq uint32; Flags Flags } | 固定头 | 3.1 |
EncodeHeader / DecodeHeader | func EncodeHeader(dst []byte, h Header) / func DecodeHeader(src []byte) (Header, error) | 头编解码 | 3.1 |
Flags / Has 等 | type Flags uint8;Has / HasAll / With / Clear / String | 标志位 | 3.1 |
Frame | type Frame struct { Cmd Cmd; Seq uint32; Flags Flags; Payload []byte } | 完整帧 | 3.2 |
Encode / EncodeInto | func Encode(f Frame) []byte / func EncodeInto(dst []byte, f Frame) []byte | 帧编码 | 3.2 |
DecodeFrom | func DecodeFrom(buf []byte) (Frame, int, error) | 从缓冲解一帧 | 3.2 |
ReadFrame / NewDecoder | func ReadFrame(r io.Reader) (Frame, error) / func NewDecoder(r io.Reader, bufSize int) *Decoder | 流式读帧 | 3.2 |
ProtocolVersion / Negotiate | const ProtocolVersion uint16 = 3 / func Negotiate(clientVersion uint16) LoginResp | 版本协商 | 3.3 |
DecodePlayerProfileV2 | func DecodePlayerProfileV2(payload []byte) (PlayerProfile, error) | 多版本解码 | 3.3 |
internal/codec(4.1–4.3)
| 符号 | 签名 | 说明 | 出处 |
|---|
Writer / NewWriter | type Writer struct{ buf []byte } / func NewWriter(capacity int) *Writer | 写缓冲 | 4.1 |
Writer.PutUint8 等 | func (w *Writer) PutUint8(v uint8) … PutUint64 / PutFloat32 | 定长写入 | 4.1 |
Writer.PutVarint / PutString | func (w *Writer) PutVarint(v uint64) / func (w *Writer) PutString(s string) error | 变长 / 前缀写入 | 4.1 |
Reader / NewReader | type Reader struct { buf []byte; pos int } / func NewReader(b []byte) *Reader | 读缓冲 | 4.1 |
Reader.GetUint8 等 | func (r *Reader) GetUint8() (uint8, error) … GetUint64 / GetVarint | 定长 / 变长读取 | 4.1 |
Reader.SliceBytes / SharesBackingArray | func (r *Reader) SliceBytes() ([]byte, error) / func SharesBackingArray(a, b []byte) bool | 零拷贝视图 | 4.2 |
SplitFrame | func SplitFrame(raw []byte) (payload []byte, err error) | 复用帧头切载荷 | 4.2 |
MoveNotify / DecodeFlat | type MoveNotify struct { PlayerID uint64; X, Y, Z float32; Speed float32; Timestamp uint64 } | 扁平化协议 | 4.3 |
ErrShortBuffer 等 | var ErrShortBuffer = errors.New("codec: 读取越界,剩余字节不足") | 越界错误 | 4.1 |
internal/kcp(5.1–5.3)
| 符号 | 签名 | 说明 | 出处 |
|---|
KCP / NewKCP | type KCP struct { ... } / func NewKCP(conv uint32, output outputFunc) *KCP | 可靠 UDP 会话 | 5.2 |
KCP.Send / Recv | func (k *KCP) Send(data []byte) int / func (k *KCP) Recv(buf []byte) int | 收发数据 | 5.2 |
KCP.Input / Update | func (k *KCP) Input(data []byte) int / func (k *KCP) Update(now uint32) | 喂包与推进 | 5.2 |
SimConfig / Simulate | type SimConfig struct { ... } / func Simulate(cfg SimConfig, streams int) []float64 | 弱网模拟 | 5.1 / 5.3 |
internal/ws(6.1–6.3)
| 符号 | 签名 | 说明 | 出处 |
|---|
Frame | type Frame struct { Fin bool; Opcode byte; Masked bool; Payload []byte } | 单帧 | 6.1 |
OpText 等 | const OpText byte = 0x1 … OpBinary 0x2 / OpClose 0x8 / OpPing 0x9 / OpPong 0xA | 操作码 | 6.1 |
ReadFrame / WriteFrame | func ReadFrame(r io.Reader, maxPayload uint64) (*Frame, error) / func WriteFrame(w io.Writer, fin bool, opcode byte, payload []byte, masked bool) error | 单帧读写 | 6.1 |
ReadMessage / ReadMessageMasked | func ReadMessage(r io.Reader, maxPayload uint64) (byte, []byte, error) | 读完整消息 | 6.1 |
Server / NewServer | type Server struct { ReadTimeout time.Duration; PingInterval time.Duration; MaxPayload uint64; ... } | 服务端 | 6.2 |
TicketManager / Issue / Verify | func (m *TicketManager) Issue(account string, connSeq uint64, ttl time.Duration, now time.Time) (string, error) | 重连票据 | 6.3 |
CloseGoingAway 等 | const CloseGoingAway uint16 = 1001 / CloseProtocolErr 1002 / ClosePolicyViolat 1003 | 关闭码 | 6.2 |
internal/session(7.1–7.3)
| 符号 | 签名 | 说明 | 出处 |
|---|
ConnID / Conn / NewConn | type ConnID uint64 / func NewConn(send func(cmd uint16, payload []byte) error) *Conn | 连接对象 | 7.1 |
Conn.Send / Close / Closed | func (c *Conn) Send(cmd uint16, payload []byte) error / func (c *Conn) Close() error | 发送与关闭 | 7.1 |
Table / NewTable | type Table struct { ... } / func NewTable() *Table | 会话表 | 7.1 |
Table.Bind | func (t *Table) Bind(account string, c *Conn) (evicted *Conn) | 绑定账号 | 7.1 / 7.2 |
Table.Lookup / Get / Remove | func (t *Table) Lookup(account string) (*Conn, bool) / func (t *Table) Get(connID ConnID) (*Conn, bool) | 查询与摘除 | 7.1 |
Registrar / Login / Kick / Migrate | func (r *Registrar) Migrate(account string, c *Conn) (old *Conn) / func (r *Registrar) Kick(account string) error | 顶号与迁移 | 7.2 |
Gateway / NewGateway | func NewGateway(table *Table, auth func(account, token string) bool, route func(cmd uint16) string) *Gateway | 网关边界 | 7.3 |
Gateway.Admit / OnCommand / Routed | func (g *Gateway) OnCommand(account string, cmd uint16) (string, error) | 准入与路由 | 7.3 |
ErrNoRoute 等 | var ErrNoRoute = errors.New("session: no route") | 错误哨兵 | 7.3 |
internal/router(8.1–8.3)
| 符号 | 签名 | 说明 | 出处 |
|---|
Kind + 三常量 | type Kind uint8;KindRequest / KindResponse / KindPush | 消息类型 | 8.1 |
Handler | type Handler func(*Context) error | 处理器 | 8.1 |
Conn | type Conn interface { ID() uint64; Send(cmd Cmd, seq uint32, flags uint8, payload []byte) error } | 连接抽象 | 8.1 |
Context / Reply / Push | type Context struct { Conn Conn; Frame Frame; ReplyCmd Cmd } / func (c *Context) Reply(payload []byte) error | 分发上下文 | 8.1 |
Router / New / Dispatch | func New() *Router / func (r *Router) Dispatch(c Conn, f Frame) error | 路由表与分发 | 8.1 |
Router.HandleRequest 等 | func (r *Router) HandleRequest(cmd, reply Cmd, h Handler) / HandleNotify / HandlePush | 注册处理器 | 8.1 |
SeqWindow / Accept | func NewSeqWindow(size uint32) *SeqWindow / func (w *SeqWindow) Accept(seq uint32) bool | 位图去重窗口 | 8.2 |
ReorderBuffer / Push | func NewReorderBuffer(cap int) *ReorderBuffer / func (b *ReorderBuffer) Push(f Frame) (ready []Frame, buffered int, overflow bool) | 乱序重排 | 8.2 |
Broadcaster / BroadcastEncoded | func NewBroadcaster() *Broadcaster / func (b *Broadcaster) BroadcastEncoded(cmd Cmd, seq uint32, flags uint8, payload []byte) (sent int) | 编一次发 N 次 | 8.3 |
WireConn | type WireConn interface { ID() uint64; WriteFrame(buf []byte) error } | 广播连接 | 8.3 |
internal/timing(9.1–9.3)
| 符号 | 签名 | 说明 | 出处 |
|---|
Clock / Cooldown / NewCooldown | type Clock func() time.Time / func NewCooldown(now Clock) *Cooldown | 技能冷却 | 9.1 |
Cooldown.Use / Ready / Remaining | func (c *Cooldown) Use(entity uint64, skill uint32, cd time.Duration) bool | 冷却判定 | 9.1 |
Watchdog / NewWatchdog | func NewWatchdog(now Clock, onExpire func(id uint64)) *Watchdog | 心跳看门狗 | 9.1 |
Wheel / New / After | func New(interval time.Duration, slots int) *Wheel / func (w *Wheel) After(d time.Duration, fn func()) uint64 | 时间轮与挂任务 | 9.2 |
WorldClock / NewWorldClock / Advance | func NewWorldClock(step time.Duration, policy Policy) *WorldClock / func (c *WorldClock) Advance(wall time.Duration) int | 墙钟折算逻辑步 | 9.3 |
WorldClock.SetMaxSteps / SetScale | func (c *WorldClock) SetMaxSteps(n int) / func (c *WorldClock) SetScale(s float64) | Tick 预算与倍速 | 9.3 |
Policy + 三常量 | type Policy int;CatchUp / Drop / SlowDown | 落后策略 | 9.3 |
internal/actor(10.1–10.3)
| 符号 | 签名 | 说明 | 出处 |
|---|
EntityID / Msg | type EntityID uint64 / type Msg struct { Cmd uint16; Seq uint32; From EntityID; Payload []byte } | 实体 ID 与消息 | 10.1 |
Entity / OutOfOrder | type Entity struct { ID EntityID; X int32; Y int32; HP int; ... } / func (e *Entity) OutOfOrder() int | 实体与乱序计数 | 10.1 / 10.2 |
Handle / Send / Snapshot | type Handle struct { ... } / func (h *Handle) Send(msg Msg) error / func (h *Handle) Snapshot() Entity | 实体句柄 | 10.1 |
Registry / NewRegistry | func NewRegistry(capacity int, policy RejectPolicy) *Registry | 实体注册表 | 10.1 |
Registry.Spawn / Route / Lookup | func (r *Registry) Spawn(id EntityID) *Handle / func (r *Registry) Route(id EntityID, msg Msg) error | 增删查与投递 | 10.1 |
Mailbox / NewMailbox / Send / Recv | func NewMailbox(capacity int, policy RejectPolicy) *Mailbox / func (m *Mailbox) Send(msg Msg) error | 有界邮箱 | 10.2 |
RejectPolicy + 四常量 | type RejectPolicy int;RejectBlock / RejectDrop / RejectDegrade / RejectDisconnect | 满时策略 | 10.2 |
internal/idem(11.1–11.3)
| 符号 | 签名 | 说明 | 出处 |
|---|
CommandID | type CommandID struct { Actor uint64; Cmd uint16; Seq uint32 } | 命令标识 | 11.2 |
Fingerprint / FingerprintOf | type Fingerprint uint64 / func FingerprintOf(cmd uint16, actor, token uint64, args ...uint64) Fingerprint | 业务指纹 | 11.2 |
Deduper / NewDeduper / Observe | func NewDeduper(ttl time.Duration, n int) *Deduper / func (d *Deduper) Observe(cmd uint16, actor, token uint64, now time.Time, args ...uint64) (Fingerprint, bool) | 去重器 | 11.2 |
Window / NewWindow | func NewWindow(ttl time.Duration, n int) *Window | 幂等窗口 | 11.1 |
Settler / NewSettler / Settle | func NewSettler(win *Window, store Store) *Settler / func (s *Settler) Settle(fp Fingerprint, now time.Time) (st State, fresh bool) | 结算器 | 11.3 |
Store / MemStore | type Store interface { Begin(key uint64) (State, bool); Commit(key uint64, st State) } / func NewMemStore() *MemStore | 持久约束 | 11.3 |
State + 三常量 | type State uint8;StateNew / StateGranted / StateDelivered | 结算态 | 11.3 |
internal/sync(12.1–12.3)
| 符号 | 签名 | 说明 | 出处 |
|---|
Vec2 / Entity / Input | type Vec2 struct{ X, Y float32 } / type Input struct { PlayerID uint32; MoveX int8; MoveY int8; Fire bool } | 世界基础类型 | 12.1 |
World / NewWorld | func NewWorld() *World | 权威世界 | 12.1 |
World.Step / Replicate / Digest | func (w *World) Step(inputs []Input) / func (w *World) Digest() uint64 | 推进与摘要 | 12.1 |
StateSyncServer / NewStateSyncServer | func NewStateSyncServer(w *World, tickRate int) *StateSyncServer | 状态同步服务端 | 12.1 |
LockstepServer / NewLockstepServer | func NewLockstepServer(players int) *LockstepServer | 帧同步服务端 | 12.1 |
LockstepServer.Submit / Advance | func (s *LockstepServer) Advance() (LockstepFrame, bool) | 收帧与推进 | 12.1 |
Snapshot / Delta / DeltaEntry | type Snapshot struct { Tick uint32; Entities []EntityState } / type Delta struct { Tick uint32; Baseline uint32; Entries []DeltaEntry } | 快照与增量 | 12.2 |
Diff / EncodeFull / EncodeDelta | func Diff(base, cur Snapshot) Delta / func EncodeFull(s Snapshot, seq uint32) []byte | 差分与编码 | 12.2 |
FieldMask + 四常量 | type FieldMask uint8;FieldPos FieldMask = 1 << iota / FieldVel / FieldHP / FieldKind | 字段掩码 | 12.2 |
Grid / NewGrid / Interest | func NewGrid(n int, cols int32, cell float32) *Grid / func (g *Grid) Interest(id uint32, radius float32, dst []uint32) []uint32 | AOI 兴趣过滤 | 12.3 |
internal/predict(13.1–13.3)
| 符号 | 签名 | 说明 | 出处 |
|---|
Vec2 / Input / Speed | type Vec2 struct { X, Y float64 } / type Input struct { Seq uint32; MoveX int8; MoveY int8 } / const Speed = 5.0 | 预测基础类型 | 13.1 |
Predictor | type Predictor struct { Pos Vec2; Pending []Input; lastSeq uint32 } | 本地预测器 | 13.1 |
Predictor.ApplyLocalInput / NextSeq | func (p *Predictor) ApplyLocalInput(in Input) Vec2 / func (p *Predictor) NextSeq() uint32 | 本地先走一步 | 13.1 |
Predictor.Reconcile | func (p *Predictor) Reconcile(serverPos Vec2, ackedSeq uint32) (pos Vec2, replayed int, err float64) | 回滚与和解 | 13.2 |
Interpolate / Extrapolate | func Interpolate(buf []Snapshot, renderTick float64) Vec2 / func Extrapolate(s Snapshot, dt float64) Vec2 | 插值与外推 | 13.3 |
internal/clock(14.1–14.3,含 rewind / fairness)
| 符号 | 签名 | 说明 | 出处 |
|---|
Source / Timeline / NewTimeline | type Source func() time.Duration / func NewTimeline(source Source) *Timeline | 时间线 | 14.1 |
Timeline.Elapsed / ForwardJumps / BackwardJumps | func (t *Timeline) ForwardJumps() int / func (t *Timeline) BackwardJumps() int | 跳变统计 | 14.1 |
Offset / Measure | type Offset struct { RTT time.Duration; Offset time.Duration } / func Measure(t1, t2, t3, t4 time.Duration) Offset | 偏移测量 | 14.1 |
Pos / History / NewHistory | type Pos struct { T time.Duration; X, Y float64 } / func NewHistory(capacity int) *History | 回滚历史(rewind) | 14.2 |
History.Push / At | func (h *History) At(t time.Duration) (Pos, bool) / func (h *History) Push(p Pos) | 回看历史点 | 14.2 |
RewindTo / HitTest | func RewindTo(serverNow, rtt, interp time.Duration) time.Duration / func HitTest(h *History, t time.Duration, ax, ay, r float64) (bool, Pos) | 回退时刻与命中 | 14.2 |
Policy / ClampRewind | type Policy struct { MaxRewind time.Duration; MaxRTT time.Duration } / func (p Policy) ClampRewind(claimed time.Duration) (time.Duration, bool) | 补偿上限(fairness) | 14.3 |
LagTracker / NewLagTracker | func NewLagTracker(baseline, spike time.Duration, window int) *LagTracker | 延迟尖峰跟踪 | 14.3 |
LagTracker.Observe / SpikeRate / Suspicious | func (t *LagTracker) SpikeRate() float64 / func (t *LagTracker) Suspicious() bool | 可疑高延迟识别 | 14.3 |
internal/authority(15.1–15.3)
| 符号 | 签名 | 说明 | 出处 |
|---|
Trust + 三常量 | type Trust uint8;Untrusted Trust = iota / Derived / Advisory | 三级信任 | 15.1 |
FieldSpec / CommandSpec | type FieldSpec struct { Name string; Trust Trust } / type CommandSpec struct { Kind string; Fields []FieldSpec } | 字段级信任契约 | 15.1 |
Registry / Register / Check | func NewRegistry() *Registry / func (r *Registry) Check(kind string, sent []string) []Violation | 契约注册与校验 | 15.1 |
Violation | type Violation struct { Command string; Field string; Reason string } | 违规描述 | 15.1 |
Vec3 / MoveProposal / MoveConfig | type Vec3 struct{ X, Y, Z float64 } / type MoveConfig struct { Tolerance float64; TeleportThreshold float64 } | 移动校验输入 | 15.2 |
ValidateMove / PathBlocked | func ValidateMove(p MoveProposal, cfg MoveConfig) MoveVerdict / func PathBlocked(from, to Vec3, step float64, solid SolidFunc) bool | 移动裁决与穿墙检测 | 15.2 |
TokenBucket / NewTokenBucket / Allow | func NewTokenBucket(capacity, refill float64, now time.Time) *TokenBucket / func (b *TokenBucket) Allow(now time.Time) bool | 令牌桶限速 | 15.3 |
Scorer / Disposition | type Scorer struct { ... } / type Disposition uint8;Allow / Throttle / Flag / Disconnect / Ban | 处置分级 | 15.3 |
internal/guard(16.1–16.3)
| 符号 | 签名 | 说明 | 出处 |
|---|
Limits | type Limits struct { MaxConnsPerIP int; MaxPendingPerIP int; MaxConnsGlobal int; ... } | 连接配额 | 16.2 |
Limiter / New / Acquire | func New(lim Limits) *Limiter / func (l *Limiter) Acquire(ip string, now time.Time) (*Ticket, error) | 限流与准入 | 16.2 |
Limiter.AllowHandshake | func (l *Limiter) AllowHandshake(ip string, now time.Time) bool | 握手令牌桶 | 16.2 |
Sealer / NewSealer / Seal / Open | func NewSealer(key []byte) (*Sealer, error) / func (s *Sealer) Seal(seq uint32, plaintext []byte) ([]byte, error) | AEAD 封包 | 16.3 |
ReplayWindow / Accept | func (w *ReplayWindow) Accept(seq uint32) bool | 重放窗口 | 16.3 |
DeriveKey / NonceLen / SeqLen | func DeriveKey(secret []byte, label string) []byte / const NonceLen = 12 / const SeqLen = 4 | 密钥派生与布局 | 16.3 |
internal/gateway + cmd/aegis(17.1–17.3)
| 符号 | 签名 | 说明 | 出处 |
|---|
Config | type Config struct { Role string; Listen string; Upstream string; ReadTimeout time.Duration; Tick time.Duration; AOIRadius float64; MaxSpeed float64 } | 进程配置 | 17.1 |
DefaultConfig | func DefaultConfig() Config | 默认配置 | 17.1 |
L1 自检:API 清单与源码逐字对齐
附录最容易腐化的地方,是签名抄错了一个参数名而没人发现。下面这段是 L1,把 API 清单编码成 Go 表,折叠源码空白后断言每个签名都能在对应包里逐字找到——它同时替本附录所有表格兜底。
// file: api_reference_test.go
// tier: L1
// verify: go test ./...
package appendix
import (
"os"
"path/filepath"
"strings"
"testing"
)
// apiTable 钉死每个 internal 包的一个代表导出符号,签名逐字取自正文代码块。
var apiTable = []struct{ pkg, sig string }{
{"proto", "type Frame struct { Cmd Cmd Seq uint32 Flags Flags Payload []byte }"},
{"proto", "const HeaderSize = 11"},
{"proto", "const MaxPayload = 1 << 20"},
{"proto", "func DecodeFrom(buf []byte) (Frame, int, error)"},
{"codec", "func NewWriter(capacity int) *Writer"},
{"codec", "func SplitFrame(raw []byte) (payload []byte, err error)"},
{"kcp", "func (k *KCP) Input(data []byte) int"},
{"ws", "func ReadFrame(r io.Reader, maxPayload uint64) (*Frame, error)"},
{"session", "func (t *Table) Bind(account string, c *Conn) (evicted *Conn)"},
{"router", "type Handler func(*Context) error"},
{"timing", "func (w *Wheel) After(d time.Duration, fn func()) uint64"},
{"actor", "type Msg struct { Cmd uint16 Seq uint32 From EntityID Payload []byte }"},
{"idem", "func FingerprintOf(cmd uint16, actor, token uint64, args ...uint64) Fingerprint"},
{"sync", "type Vec2 struct{ X, Y float32 }"},
{"predict", "const Speed = 5.0"},
{"clock", "func Measure(t1, t2, t3, t4 time.Duration) Offset"},
{"rewind", "func RewindTo(serverNow, rtt, interp time.Duration) time.Duration"},
{"fairness", "func NewLagTracker(baseline, spike time.Duration, window int) *LagTracker"},
{"authority", "func ValidateMove(p MoveProposal, cfg MoveConfig) MoveVerdict"},
{"guard", "func NewSealer(key []byte) (*Sealer, error)"},
{"gateway", "func DefaultConfig() Config"},
}
// fold 折叠空白,使「逐字一致」在 token 层面成立而不苛求排版。
func fold(s string) string { return strings.Join(strings.Fields(s), " ") }
// inPackage 在任意 ../chNN/internal/<pkg> 下折叠源码,查找签名是否逐字出现。
func inPackage(root, pkg, sig string) bool {
found := false
_ = filepath.Walk(root, func(p string, info os.FileInfo, err error) error {
if err != nil || info.IsDir() || !strings.HasSuffix(p, ".go") || strings.HasSuffix(p, "_test.go") {
return nil
}
if filepath.Base(filepath.Dir(p)) != pkg {
return nil
}
b, _ := os.ReadFile(p)
if strings.Contains(fold(string(b)), sig) {
found = true
}
return nil
})
return found
}
func TestAPIListMatchesSource(t *testing.T) {
root, _ := filepath.Abs("..")
if _, err := os.Stat(filepath.Join(root, "ch03", "internal", "proto", "header.go")); err != nil {
t.Skip("卷一源码树不在 ../chNN,跳过符号核对")
}
for _, e := range apiTable {
if !inPackage(root, e.pkg, fold(e.sig)) {
t.Errorf("%s: 源码里找不到签名 %s", e.pkg, e.sig)
}
}
}
fold 把任意空白折成单空格,所以「逐字一致」在 token 层面成立、不苛求排版;inPackage 跳过 _test.go,只认非测试源码。源码树不在 ../chNN 时它会 t.Skip,故只有本附录的模块里 go test ./... 依然全绿。
阅读下一节:附录 B 环境与复现速查
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。