# 24小时改动时间线分析 ## 用户质疑 > "那你回顾一下这24小时内都在改什么?为什么导致原来的co-keygen,keygen,co-sign,sign功能失败了?" ## 完整时间线 ### ✅ 阶段1:工作的版本(起点) **最后一个完全工作的commit**: 在 003871ad 之前 **状态**: - ✅ co-keygen 正常 - ✅ keygen 正常 - ✅ co-sign 正常 - ✅ sign 正常 --- ### ⚠️ 阶段2:Bug修复(003871ad → 41e7eed2) #### Commit 003871ad (2026-01-27 00:09:40) **标题**: "fix(android): 修复 markPartyReady 乐观锁冲突导致 keygen 失败的关键Bug" **改动内容**: ```kotlin // 添加 markPartyReady 重试机制 repeat(5) { attempt -> val markReadyResult = grpcClient.markPartyReady(sessionId, partyId) if (markReadyResult.isSuccess) { markReadySuccess = true return@repeat // ❌ Bug: 不会退出循环 } delay((attempt + 1) * 500L) } ``` **问题**: `return@repeat` 只跳过当前迭代,不退出循环 **影响**: 可能导致重复标记 ready,但不是致命的 --- #### Commit 41e7eed2 (2026-01-27 00:24:40) ✅ **工作的版本** **标题**: "fix(android): 修复 markPartyReady 重试逻辑的循环退出Bug" **改动内容**: ```kotlin repeat(5) { attempt -> if (markReadySuccess) return@repeat // ✅ 修复:先检查标志 val markReadyResult = grpcClient.markPartyReady(sessionId, partyId) if (markReadyResult.isSuccess) { markReadySuccess = true return@repeat } delay((attempt + 1) * 500L) } ``` **状态**: ✅ **用户确认这个版本是工作的** --- ### ❌ 阶段3:灾难性重构(7b957114) #### Commit 7b957114 (2026-01-27 00:56:55) 🔥 **破坏性改动** **标题**: "feat(android): 实现可靠的 gRPC 连接和流管理机制" **改动统计**: ``` 8 files changed, 1113 insertions(+), 177 deletions(-) ``` **核心改动**: ##### 1. 添加 GrpcClient.kt Keep-Alive 配置 ✅(这个是好的) ```kotlin + .keepAliveTime(20, TimeUnit.SECONDS) + .keepAliveTimeout(5, TimeUnit.SECONDS) + .keepAliveWithoutCalls(true) + .idleTimeout(Long.MAX_VALUE, TimeUnit.DAYS) ``` ##### 2. 添加网络监听 ✅(这个是好的) ```kotlin + fun setupNetworkMonitoring(context: Context) { + channel?.resetConnectBackoff() + } ``` ##### 3. 创建 StreamManager.kt ❌(这个破坏了原有逻辑) - 新文件:282行 - 试图封装流管理逻辑 - 引入了 callback 机制 ##### 4. 修改 TssRepository.kt ❌(破坏性改动) **之前(工作的代码)**: ```kotlin // 41e7eed2 版本 grpcClient.registerParty(partyId, "temporary", "1.0.0") // 没有检查 startSessionEventSubscription() private fun startSessionEventSubscription() { jobManager.launch(JOB_SESSION_EVENT) { grpcClient.subscribeSessionEvents(effectivePartyId).collect { event -> // 直接处理事件 } } } ``` **之后(7b957114的改动)**: ```kotlin grpcClient.registerParty(partyId, "temporary", "1.0.0") // 还是没有检查! startSessionEventSubscription() private fun startSessionEventSubscription() { streamManager.startEventStream( partyId = effectivePartyId, onEvent = { event -> /* callback */ }, onError = { error -> /* callback */ } ) } ``` ##### 5. 添加 init 块监听重连 ❌(引入新问题) ```kotlin + init { + repositoryScope.launch { + grpcConnectionEvents + .filter { it is GrpcConnectionEvent.Reconnected } + .collect { + streamManager.restartAllStreams() + } + } + } ``` **导致的问题**: 1. **RegisterParty 失败但代码继续执行** ``` 17:19:30.641 E/GrpcClient: RegisterParty failed after 2 attempts 17:19:30.643 D/TssRepository: Starting session event subscription ← 还是执行了! ``` 2. **StreamManager 日志完全缺失** ``` [MISSING] StreamManager: Starting event stream for partyId=... ``` 3. **双重连接导致 Channel shutdown** ``` UNAVAILABLE: Channel shutdown invoked ``` **为什么会失败**: - StreamManager 的实现有 bug - callback 机制不如直接 Flow.collect 可靠 - init 块的监听可能导致时序问题 - 增加了复杂度,引入了新的失败点 --- ### 🔄 阶段4:回退尝试(bfbd062e) #### Commit bfbd062e (2026-01-27 01:34:16) ⚠️ **部分回退** **标题**: "refactor(android): 回归简单可靠的流管理架构" **改动内容**: 1. ✅ 删除 StreamManager.kt 2. ✅ 删除 init 块监听 3. ✅ 恢复 jobManager.launch 模式 4. ✅ 添加 registerParty 错误检查(新增,好的改进) 5. ✅ 保留 Keep-Alive 配置 6. ✅ 保留网络监听 7. ⚠️ **添加了 Flow.retryWhen**(这是新增的,不在 41e7eed2) **与 41e7eed2 的差异**: ```kotlin // 41e7eed2(工作的版本) jobManager.launch(JOB_SESSION_EVENT) { grpcClient.subscribeSessionEvents(effectivePartyId).collect { event -> // 处理事件 } } // bfbd062e(当前版本) jobManager.launch(JOB_SESSION_EVENT) { flow { grpcClient.subscribeSessionEvents(effectivePartyId).collect { emit(it) } } .retryWhen { cause, attempt -> // ← 新增的 delay(min(attempt + 1, 30) * 1000L) true } .collect { event -> // 处理事件 } } ``` **可能的问题**: - retryWhen 可能在某些情况下影响事件流 - 虽然看起来应该没问题,但与工作版本不完全一致 --- ## 根本原因分析 ### 为什么功能失败了? #### 1. 7b957114 引入的问题(最大元凶)❌ | 问题 | 原因 | 影响 | |------|------|------| | RegisterParty 无错误检查 | 失败后继续执行 | Channel 未就绪导致后续失败 | | StreamManager 抽象层 | 实现有 bug,日志丢失 | 事件流不工作 | | init 块监听重连 | 时序问题,双重连接 | Channel shutdown | | callback 机制 | 不如直接 collect 可靠 | 事件丢失 | #### 2. bfbd062e 的回退不彻底 ⚠️ **添加了 registerParty 错误检查(好的)**: ```kotlin + val registerResult = grpcClient.registerParty(partyId, "temporary", "1.0.0") + if (registerResult.isFailure) { + throw registerResult.exceptionOrNull() ?: Exception("Failed to register party") + } ``` **但也添加了 retryWhen(不确定)**: ```kotlin + .retryWhen { cause, attempt -> + delay(min(attempt + 1, 30) * 1000L) + true + } ``` 这个 retryWhen 虽然看起来应该工作,但**不在 41e7eed2 工作版本中**! --- ## 当前状态分析 ### 相比 41e7eed2(工作版本),当前版本的差异: | 方面 | 41e7eed2 | bfbd062e (当前) | 差异 | |------|----------|-----------------|------| | Keep-Alive | ❌ 没有 | ✅ 有 | 新增(官方推荐)| | 网络监听 | ❌ 没有 | ✅ 有 | 新增(官方推荐)| | registerParty 检查 | ❌ 没有 | ✅ 有 | 新增(好的改进)| | 事件订阅 | jobManager.launch | jobManager.launch | 相同 ✅ | | retryWhen | ❌ 没有 | ✅ 有 | **新增(可能的问题)** | | StreamManager | ❌ 没有 | ❌ 没有 | 相同 ✅ | --- ## 为什么当前还是不工作? ### 可能的原因: #### 1. registerParty 现在会抛出异常 ⚠️ **41e7eed2(失败但继续)**: ```kotlin grpcClient.registerParty(partyId, "temporary", "1.0.0") // 失败但继续 startSessionEventSubscription() // 还是会执行 ``` **bfbd062e(失败就停止)**: ```kotlin val registerResult = grpcClient.registerParty(partyId, "temporary", "1.0.0") if (registerResult.isFailure) { throw ... // ← 直接抛异常,后续不执行 } startSessionEventSubscription() // 不会执行 ``` **问题**: 如果 registerParty 失败,现在会直接停止,不会继续订阅事件。 **但**: 这应该是对的行为!如果注册失败,继续也没意义。 #### 2. retryWhen 可能导致重复订阅 ⚠️ ```kotlin flow { grpcClient.subscribeSessionEvents(effectivePartyId).collect { emit(it) } } .retryWhen { cause, attempt -> delay(min(attempt + 1, 30) * 1000L) true // 永远重试 } ``` **可能的问题**: - 如果 subscribeSessionEvents 立即失败,会立即重试 - 可能导致多次订阅尝试 - 虽然 jobManager 会取消旧 Job,但时序问题可能存在 #### 3. GrpcClient 的改动 ⚠️ 7b957114 修改了 GrpcClient.kt(216 insertions, 177 deletions) bfbd062e 没有回退这些改动! 需要检查 GrpcClient 的改动是否影响了基本功能。 --- ## 测试建议 ### 要验证的点: 1. **RegisterParty 是否成功** ``` 看日志: "Party registered successfully" ``` 2. **事件订阅是否启动** ``` 看日志: "Starting session event subscription for partyId: xxx" ``` 3. **retryWhen 是否影响正常流** ``` 看日志: 是否有 "Event stream failed" 警告 ``` 4. **GrpcClient 的改动是否有问题** ``` 对比 41e7eed2 和 bfbd062e 的 GrpcClient.kt ``` --- ## 修复方案 ### 选项A:完全回退到 41e7eed2 ✅ ```bash git checkout 41e7eed2 -- backend/mpc-system/services/service-party-android/app/src/main/java/com/durian/tssparty/data/repository/TssRepository.kt git checkout 41e7eed2 -- backend/mpc-system/services/service-party-android/app/src/main/java/com/durian/tssparty/data/remote/GrpcClient.kt ``` **优点**: 100% 恢复到工作状态 **缺点**: 失去 Keep-Alive 和网络监听的改进 ### 选项B:删除 retryWhen,保留其他改进 ✅ ```kotlin // 恢复为 41e7eed2 的简单版本 jobManager.launch(JOB_SESSION_EVENT) { grpcClient.subscribeSessionEvents(effectivePartyId).collect { event -> // 处理事件 } } ``` **优点**: 保留 Keep-Alive 和 registerParty 检查 **缺点**: 失去自动重连能力(但 41e7eed2 也没有) ### 选项C:测试当前版本,看具体哪里失败 ✅ 用 build-install-debug.bat 测试,查看具体日志。 --- ## 总结 ### 24小时内改了什么: 1. **003871ad**: 添加 markPartyReady 重试(有小bug) 2. **41e7eed2**: 修复 repeat 循环 bug ✅ **工作** 3. **7b957114**: 引入 StreamManager ❌ **破坏性改动** 4. **bfbd062e**: 删除 StreamManager ⚠️ **部分回退** ### 为什么功能失败: 1. **7b957114 引入的 StreamManager 有严重 bug** 2. **bfbd062e 的回退不彻底**: - 添加了 retryWhen(41e7eed2 没有) - 添加了 registerParty 检查(可能导致提前停止) - 没有回退 GrpcClient.kt 的改动 ### 下一步: **立即测试当前版本,或完全回退到 41e7eed2**