进程内响应缓存
说明
cache 管理单个网关进程内有容量上限的响应缓存,最多按最近最少使用顺序保存 8,192 份不透明响应正文。缓存资格、请求身份和成功判定属于数据面;本包只负责确定性缓存键和相互隔离的字节存储。它没有 TTL、持久化、Redis 同步或跨进程失效机制。
对外接口
New() *DualCache创建已初始化的 8,192 项 LRU。容量是编译期常量,只有该常量非法时才会 panic;这表示程序缺陷,而不是运行期存储失败。网关启动时创建供数据面共享的实例。Key(parts ...string) string返回小写 SHA-256 摘要。它按顺序写入每个片段,并在每段后追加零字节,因此不同分段方式不会退化成相同拼接文本。调用方负责提供所有会改变响应的维度,包括调用方范围、操作、公开模型、请求正文、部署配置和路由上下文。(*DualCache).Get(key string) ([]byte, bool)命中时返回新分配的副本和 true,未命中时返回 nil 和 false。修改返回切片不会改变缓存内容。(*DualCache).Set(key string, value []byte)先复制输入再写入。调用方以后复用或修改原切片不会影响缓存。写入会更新最近使用顺序,容量满时静默淘汰最久未使用项。(*DualCache).Flush()清空当前实例的全部记录。网关管理流程用它使本地响应失效;预算、日志、请求队列和其他进程不受影响。
本包不登记 HTTP 路由。internal/dataplane 执行读取与写入,internal/gateway 负责创建实例和管理端清空。
内部核心实现
DualCache 包装 hashicorp/golang-lru/v2 提供的并发安全泛型 LRU。New 把容量固定为 8,192,使内存增长按记录数封顶。Key 将 UTF-8 字节直接流入 SHA-256,显式分隔符保留片段边界,十六进制编码得到适合 LRU 映射的稳定字符串。
Set 分配等长切片并复制,再调用 Add;Get 先取得内部切片,命中后重新分配并复制。本包在读写两个方向都不转移内部字节所有权,避免处理函数复用缓冲区时产生数据竞争或意外破坏,代价是每次读写完整复制一次。LRU 库负责映射和新旧顺序的并发串行化。未命中、替换和容量淘汰都是正常行为,不返回错误。不支持 nil 接收者;空键和零长度值是普通记录。
外围执行顺序由数据面控制:扩展检查通过后才读缓存,只有符合条件的完整响应才写入。流式失败和协议决策不在本包内,因此直接调用 Set 会按设计绕过这些业务规则。
测试依赖
cache_test.go 验证 Flush、零字节片段分隔以及读写两侧的复制边界。运行 go test ./internal/util -count=1;测试完全在内存中。
源码职责与入口
cache.go是全部生产实现,定义cacheEntries、DualCache、一次性跟踪日志、构造、SHA-256 键生成、复制读取与写入以及清空。公开入口为New、Key、Get、Set、Flush。cache_test.go是失效、缓存键分帧和切片所有权的包级契约测试。