fix: keep participant changes out of channel pts
(cherry picked from commit 07b2497664bd108dec84f6cfe43715540faf2688)
This commit is contained in:
parent
23a2b2aff7
commit
6fd690a06e
10 changed files with 184 additions and 115 deletions
|
|
@ -127,7 +127,7 @@ status 取值:done(真实实现) / stub(兼容响应) / todo(已发现未实
|
|||
|---|---|---|---|
|
||||
| updates.getState | done | real | auth_key+user 维度持久化 update_states;账号级当前 pts 报告**最大连续已提交 pts**(MaxContiguousPts,非 allocator 最大已分配值),避免同设备换号/多账号串差分,也避免越过在途空洞 |
|
||||
| updates.getDifference | done | real | 按 user_id 从 user_update_events 拉取 pts 后增量;只返回从客户端 pts 起**连续**的事件(遇在途空洞即截断),超 100 条置 differenceSlice;支持 new_message、read_history_inbox/read_history_outbox(私聊与 channel peer,channel read 映射 updateReadChannelInbox)、edit_message、message_reactions(输出带最新 `message.reactions` 的 affected message + `updateMessageReactions`,并按 viewer 重取最新聚合,避免 TDesktop 离线恢复时本地 message cache 不刷新)、delete_messages、contacts_reset、dialog pinned/order/manual unread、peer_settings、dialog filters/folder peers 与 noop gap;消息事件携带 fwd/reply 所需 users/chats,payload 来自 durable log。**账号级绝不返回 `differenceTooLong`**:已核对 TDesktop 基线 `api_updates.cpp:516`——对账号级 differenceTooLong 只打一行日志、不读 pts 且漏 `setRequesting(false)`,会永久锁死 update 引擎(`:689` 早退,重连/新 session 不可恢复);落后客户端改用 `differenceSlice` 续传。因此 `user_update_events` **永久保留、不做 retention 裁剪**(对齐 参考实现),详见 docs/performance-audit.md 附录 C |
|
||||
| updates.getChannelDifference | done | real-channel | 超级群/频道使用 channel 维度 durable log:`channel_update_events(channel_id, pts, pts_count, ...)`;按 channel pts 返回 `channelDifferenceEmpty/channelDifference/channelDifferenceTooLong`,limit cap=100;`pts < 0` 或 `pts > current_channel_pts` 返回 `PERSISTENT_TIMESTAMP_INVALID`;当前 member 的 `available_min_pts` 会抬高请求 pts,避免新加入/重新加入成员拉到入群前 participant/admin/settings 事件;公共 username 频道允许非成员以只读预览身份拉可见差分并返回 synthetic read dialog,私有频道和禁看用户仍返回权限错误;当 `current_channel_pts-pts > cap` 时返回带当前 dialog pts 和最新有界消息快照的 `channelDifferenceTooLong`,避免大频道旧 pts 客户端循环拉大量页;普通 difference 优先使用事件 payload 中的 message/participant 快照,连续编辑/删除后不会被当前消息状态污染;本页消息的 sender/send_as/fwd_from/reply_to/action peers 会随 users/chats 返回,禁止复用 user_update_events |
|
||||
| updates.getChannelDifference | done | real-channel | 超级群/频道使用 channel 维度 durable log:`channel_update_events(channel_id, pts, pts_count, ...)`;按 channel pts 返回 `channelDifferenceEmpty/channelDifference/channelDifferenceTooLong`,limit cap=100;`pts < 0` 或 `pts > current_channel_pts` 返回 `PERSISTENT_TIMESTAMP_INVALID`;当前 member 的 `available_min_pts` 会抬高请求 pts,避免新加入/重新加入成员拉到入群前消息类 durable 事件;公共 username 频道允许非成员以只读预览身份拉可见差分并返回 synthetic read dialog,私有频道和禁看用户仍返回权限错误;当 `current_channel_pts-pts > cap` 时返回带当前 dialog pts 和最新有界消息快照的 `channelDifferenceTooLong`,避免大频道旧 pts 客户端循环拉大量页;普通 difference 优先使用事件 payload 中的 message 快照,连续编辑/删除后不会被当前消息状态污染;`updateChannelParticipant` 不进入 channel pts log,成员权限/封禁状态靠在线 `updateChannelParticipant/updateChannel` 与 `channels.getFullChannel/getParticipants/getParticipant` 刷新;本页消息的 sender/send_as/fwd_from/reply_to/action peers 会随 users/chats 返回,禁止复用 user_update_events |
|
||||
|
||||
### 兼容硬约束:pts / pts_count(跨所有产生 update 的 RPC)
|
||||
|
||||
|
|
@ -279,7 +279,7 @@ outbox 多 worker 并发 + 发送事务乱序提交 → **主动推送可能乱
|
|||
| channels.updateUsername | done | real | creator 可设置/清除频道或超级群主 username;PG 事务内更新 `channels.username` 与 `channel_usernames`,大小写不敏感唯一约束兜底,成功后向在线成员推 `updateChannel` |
|
||||
| channels.getAdminedPublicChannels | done | real | 返回当前用户 active creator/admin 且带主 username 的公开 channel/supergroup,用于 TDesktop public username limit/选择入口 |
|
||||
| channels.toggleSignatures | done | real-minimal | creator/change_info admin 可切换 `channels.signatures` 并返回/推送 `updateChannel`;profiles_enabled 先不单独持久化 |
|
||||
| channels.togglePreHistoryHidden | done | real-minimal | creator 可切换 `channels.pre_history_hidden`,返回/在线推 `updateChannel`,`getFullChannel` 暴露 `hidden_prehistory`;新加入/导入/受邀成员按当前 `top_message_id` 初始化 `available_min_id/read_inbox`,并按加入前 channel pts 初始化 `available_min_pts`,避免看到旧历史或补到入群前成员事件 |
|
||||
| channels.togglePreHistoryHidden | done | real-minimal | creator 可切换 `channels.pre_history_hidden`,返回/在线推 `updateChannel`,`getFullChannel` 暴露 `hidden_prehistory`;新加入/导入/受邀成员按当前 `top_message_id` 初始化 `available_min_id/read_inbox`,并按加入前 channel pts 初始化 `available_min_pts`,避免看到旧历史或补到入群前消息类 durable 事件 |
|
||||
| channels.toggleSlowMode | done | real-minimal | change_info 管理员可持久化 `channels.slowmode_seconds`,`Channel.slowmode_enabled/ChannelFull.slowmode_seconds` 可见;普通成员发送按 `channel_members.slowmode_last_send_date` 返回 `SLOWMODE_WAIT_X`,管理员/creator 豁免 |
|
||||
| channels.setStickers | stub | empty-only | 当前无群贴纸集 store;仅 megagroup + `inputStickerSetEmpty` 清空入口做权限校验 no-op 成功,非空 sticker set 返回 `STICKERSET_INVALID`,避免 TDesktop 误以为贴纸集已落库 |
|
||||
| channels.reorderUsernames | stub | permission-ok | 当前无 Fragment/多 username 模型,限制 order<=32、校验 change_info 后返回 BoolTrue |
|
||||
|
|
@ -323,8 +323,8 @@ outbox 多 worker 并发 + 发送事务乱序提交 → **主动推送可能乱
|
|||
| channels.readHistory | done | real | TDesktop 可能直接调用 channels.readHistory;语义同 messages.readHistory(InputPeerChannel),含发送方 `updateReadChannelOutbox` 在线通知 |
|
||||
| channels.deleteMessages | done | real-channel | 管理员/作者权限校验后软删单份 channel messages,生成有界 `updateDeleteChannelMessages`,`pts_count=len(ids)`,单次 id cap=1000 |
|
||||
| channels.deleteHistory | done | real-partial | `for_everyone` 执行一个有界管理员删除 page 并推 `updateDeleteChannelMessages`,单批 cap=1000;该 TL 返回 `Updates` 且 TDesktop 不读取 offset,禁止在同步 RPC 内循环构造超大 id/update;非 for_everyone 只清当前用户可见历史/read/dialog,不写扩散、不生成超大 update |
|
||||
| channels.editAdmin | done | real | creator 或具备 add_admins 的 admin 可更新 admin rights/rank;非 creator 只能授予自己拥有的权限;禁止改 creator;写 `channel_participant` durable event,返回/在线推 `updateChannelParticipant/updateChannel/updateChannelTooLong(pts)` |
|
||||
| channels.editBanned | done | real | creator 或具备 ban_users 的 admin 可更新 banned rights/kicked 状态,刷新 participants/admin/banned/kicked 计数;写 `channel_participant` durable event,返回/在线推 `updateChannelParticipant/updateChannel/updateChannelTooLong(pts)` |
|
||||
| channels.editAdmin | done | real | creator 或具备 add_admins 的 admin 可更新 admin rights/rank;非 creator 只能授予自己拥有的权限;禁止改 creator;写 admin log,不占 channel pts、不写 `channel_update_events`;返回/在线推 `updateChannelParticipant + updateChannel`,离线设备通过 full channel/participants 刷新状态 |
|
||||
| channels.editBanned | done | real | creator 或具备 ban_users 的 admin 可更新 banned rights/kicked 状态,刷新 participants/admin/banned/kicked 计数;写 admin log,不占 channel pts、不写 `channel_update_events`;返回/在线推 `updateChannelParticipant + updateChannel`,若后续产生可见踢人/加人 service message,则 service message 单独占 channel pts |
|
||||
| channels.editTitle | done | real | creator/change_info admin 可改标题;写 megagroup service message `messageActionChatEditTitle` 与 channel pts,返回 `updateChannel + updateNewChannelMessage` |
|
||||
| channels.editPhoto | done | real-photo | change_info 权限校验后解析 `inputChatPhoto`:`inputChatUploadedPhoto` 组装上传→建 Photo,`inputChatPhoto{inputPhoto}` 引用已存在照片,`inputChatPhotoEmpty`/`inputPhotoEmpty` 清除;落 `channels.photo_id/photo_dc_id/photo_stripped` 反范式列,`tgChannel.Photo`(ChatPhoto)/`tgChannelFull.ChatPhoto` 渲染真实头像,返回 `updateChannel` + 推 channel state;服务端无 Files 时按 `PHOTO_INVALID` 处理;in-history `MessageActionChatEditPhoto` service 消息留 todo |
|
||||
| channels.deleteChannel | done | real | creator 权限,标记 channel deleted,返回/推送 `updateChannel + channelForbidden`,dialog 列表过滤 deleted channel;后续 admin log 细化 |
|
||||
|
|
@ -417,4 +417,4 @@ outbox 多 worker 并发 + 发送事务乱序提交 → **主动推送可能乱
|
|||
|
||||
| method/type_id | first_seen | raw_note |
|
||||
|---|---|---|
|
||||
| — | — | 当前无未实现 RPC trace |
|
||||
| — | — | 当前无未实现 RPC trace |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue