sonnet 5 ,只搞了 golang 版本。三次提示词,简单 review 了下,应该是 ok 了。
仓库: https://github.com/lesismal/batchflight
第一次提示词:
batch flight
背景
关于 single flight
社区已有 single flight 算法,通常是并发的上游对下游的调用时,合并成单个对下游的调用(比如数据库、缓存等基础设施)、返回相同的结果给上游,减轻对下游的压力。 single flight 实现,主要是简单等待,因为是上游大量并发请求、并且下游的操作可能是数据层、耗时久,高并发时段的热点接口能够较多地对多个并发请求合并、起到优化效果。
关于广播风暴
对于其他一些场景,比如:
- IM 聊天软件,群聊时的消息的广播,假如 100 个玩家,每个玩家 1 秒发送一个消息,如果每个消息都直接广播给所有对应的其他玩家,一共就需要发送 100100 个消息,对应 100100 个 syscall write 。如果在线数量更大、消息数量更多,则会形成广播风暴。
- 多人游戏,例如 MMORPG 、FPS 、MOBA 游戏,用户操作和聊天都涉及到广播,也有广播风暴的压力、需要优化。
广播风暴的优化,通常都有这种合并的批次优化,比如收集当前待发送的信息,定时器 50ms 把当前待发送的消息放到一起广播一次。
广播风暴的场景,多数是主动推送消息,对下游的操作主要是单个 syscall Write ,速度很快,不像数据层消耗那么久。所以需要加定时等待的功能,否则未必能合并多少、优化效果不明显。
需求
用 golang 实现一个优化广播风暴的算法,名字叫 batch flight 。 对应的本 github 仓库 golang 包名为:"github.com/lesismal/batchflight" 。
第二次提示词:
不是用 Writer 的方式实现,而是参考标准库的方式,sync/singleflight 包提供了 Group 和它的接口: type Group struct { // contains filtered or unexported fields }
func (g *Group) Do(key string, fn func() (any, error)) (v any, err error, shared bool) func (g *Group) DoChan(key string, fn func() (any, error)) <-chan Result func (g *Group) Forget(key string)
batchflight 提供类似的 Group 和接口,但需要额外增加等待时间的参数: type Group struct { // contains filtered or unexported fields }
func (g *Group) Do(key string, wait time.Duration, fn func() (any, error)) (v any, err error, shared bool) func (g *Group) DoChan(key string, wait time.Duration, fn func() (any, error)) <-chan Result func (g *Group) Forget(key string)
第三次提示词:
修改 batchflight 提供的接口,原来的单个 func 参数调整为两个 func 参数:
- 第一个 func 参数,用于处理等待期间准备数据整合之类的操作
- 第二个 func 参数,用于把等待期间第一个 func 整合的数据做最终的处理
另外增加一个 DoAsync 方法,调用后无需等待执行完毕。
func (g *Group) Do(key string, wait time.Duration, fn func() (any, error)) (v any, err error, shared bool) func (g *Group) DoChan(key string, wait time.Duration, fn func() (any, error)) <-chan Result func (g *Group) Forget(key string)