Repository navigation
fix(timeline): 冷会话回放每页只算本页,不再逐页重算整个会话 - #1723
Merged
Merged
Conversation
回放 SQL 每取一页(256 行),都要先把整个会话的历史行和事件聚合两遍 (message_rows、changed_messages,都标了 MATERIALIZED),LIMIT 截不住, 一次回放的数据库工作量是"页数 × 会话规模"。Memoh-Cloud #695 中,Channel 重启后 8 条连接被这条查询占满数小时,配置保存拿不到连接而超时。 - 已被 checkpoint 折叠的消息,之后的编辑、删除不再让它回到上下文:摘要按 它的行记录的样子代表它。changed_messages 因此删掉,合成时的 changedSince 和 CheckpointMessage.EventCursor 一并去掉, ClassifyHistoryCheckpointMessages 不再关联事件表。 - 每个候选事件只查它自己那条消息的历史行(走 (session_id, source_message_id) 索引)来判断是否被折叠;先按游标取够 一页,再只对这一页计算并累计字节。 合成的 3 万事件会话(2k 未折叠)上,一次完整回放从约 3.0 s 降到约 0.19 s, 每页约 3 ms。 Refs felinics/Memoh-Cloud#695 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Author
Type
Summary
ListSessionEventsBySessionPageBeforeWithinBytes占满数小时,Platforms 配置保存拿不到连接,30 秒后超时。原因:
LoadEventsForReplay按页(256 行)循环,但每一页的 SQL 都先把整个会话重算一遍:message_rows:会话全部可见历史行关联各自的来源事件,从event_data解出event_cursor再按消息聚合;changed_messages:已折叠消息关联它们的全部事件,再解一遍event_cursor、再聚合;octet_length(event_data::text)并累计。这些 CTE 都标了
MATERIALIZED,LIMIT截不住,一次回放的数据库工作量是"页数 × 会话规模"。这个 PR 的改动:
changed_messages因此整段删掉;合成时的changedSince和CheckpointMessage.EventCursor一并去掉;ClassifyHistoryCheckpointMessages不再关联事件表。这是 feat(bots): add runtime diagnostics workbench #695 评论里讨论过的取舍。(session_id, source_message_id)索引),判断是否被折叠;先按游标取够一页,再只对这一页计算并累计字节。进程侧 64 MiB 预算和逐页字节上限的语义不变。需要知道的行为差异:
TestBuildMentionGatesOnWatermarkNotFolding),这里没有另做处理。不在这个 PR 里:
ListHistoryMessagesAfterWithinBytes(Server 侧,单独排查)。(session_id, received_at_ms)加增量排序,最后一页会把已折叠的剩余事件扫一遍(每个事件一次索引查询),整次回放仍只是 O(会话事件数)。Related Issues
Refs felinics/Memoh-Cloud#695
Validation
测试
go test ./internal/chat/... ./internal/channel/discuss/ ./internal/channel/inbound/通过。TestPostgres*:internal/chat/timeline、internal/chat/message、internal/chat/checkpoint、cmd/agent、internal/agent/application全部通过。TestPostgresReplayAndClassificationFollowTheCheckpoint改为断言:被折叠的消息在折叠后被编辑,也不再回放。TestComposeContextWithCheckpointKeepsAnEditedMessageFolded取代原来"折叠后有变化就重新组成"的测试。golangci-lint run ./internal/chat/...无告警。回放耗时对比(本地 PostgreSQL 18;合成会话共 30,000 个事件,每个约 3.3 KB,其中 2,048 个在 checkpoint 之后;按
LoadEventsForReplay的方式逐页执行到结束)EXPLAIN 的计划是:
idx_session_events_session_received倒序索引扫描,每个事件在idx_bot_history_messages_session_source上做一次索引查询,没有整会话的聚合。这是合成数据上的结果,没有在生产数据和 Cloud 的 RLS 上测过。开发环境(本分支启动的隔离 devenv:docker compose,换了端口,数据卷全新)
MK数字,以及摘要对应的SUMMARY),所以回复内容本身就反映了这次请求的上下文。PUT /bots/{id}/channel/telegram返回 200,耗时 59 ms)。channel容器让这个会话变冷,再发 MK21。timeline replay payload admitted ... event_count=2 persisted_event_count=4,即 4 个已持久化事件里,被折叠的 MK11、MK12 在 SQL 里就被排除,只回放了 2 个。SUMMARY, MK13, MK20;重启后回复SUMMARY, MK13, MK20, MK21。冷回放后的上下文和重启前一致,只多了新消息,被折叠的消息没有以原文重新出现。未验证:开发环境里没有验证"渠道消息折叠后又被编辑",因为 fake Telegram 不能注入编辑事件;这个行为由上面的 PostgreSQL 集成测试覆盖。也没有做连接池压力测试。
Screenshots / Recordings
以下截图来自 Agent 在本分支开发环境里的操作,只说明流程走通,不代表人工 QA;回放的依据是上面的 Channel 日志。
Telegram Discuss 会话:Channel 重启前,bot 看到

SUMMARY, MK13, MK20;重启后第一条消息 MK21 经冷回放,bot 看到SUMMARY, MK13, MK20, MK21。在 Platforms 页面保存 Telegram 平台配置成功(这里只说明保存流程走通,不是压力测试)。

Human QA
🤖 Generated with Claude Code