10 KiB
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"
改动内容:
// 添加 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"
改动内容:
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 配置 ✅(这个是好的)
+ .keepAliveTime(20, TimeUnit.SECONDS)
+ .keepAliveTimeout(5, TimeUnit.SECONDS)
+ .keepAliveWithoutCalls(true)
+ .idleTimeout(Long.MAX_VALUE, TimeUnit.DAYS)
2. 添加网络监听 ✅(这个是好的)
+ fun setupNetworkMonitoring(context: Context) {
+ channel?.resetConnectBackoff()
+ }
3. 创建 StreamManager.kt ❌(这个破坏了原有逻辑)
- 新文件:282行
- 试图封装流管理逻辑
- 引入了 callback 机制
4. 修改 TssRepository.kt ❌(破坏性改动)
之前(工作的代码):
// 41e7eed2 版本
grpcClient.registerParty(partyId, "temporary", "1.0.0") // 没有检查
startSessionEventSubscription()
private fun startSessionEventSubscription() {
jobManager.launch(JOB_SESSION_EVENT) {
grpcClient.subscribeSessionEvents(effectivePartyId).collect { event ->
// 直接处理事件
}
}
}
之后(7b957114的改动):
grpcClient.registerParty(partyId, "temporary", "1.0.0") // 还是没有检查!
startSessionEventSubscription()
private fun startSessionEventSubscription() {
streamManager.startEventStream(
partyId = effectivePartyId,
onEvent = { event -> /* callback */ },
onError = { error -> /* callback */ }
)
}
5. 添加 init 块监听重连 ❌(引入新问题)
+ init {
+ repositoryScope.launch {
+ grpcConnectionEvents
+ .filter { it is GrpcConnectionEvent.Reconnected }
+ .collect {
+ streamManager.restartAllStreams()
+ }
+ }
+ }
导致的问题:
-
RegisterParty 失败但代码继续执行
17:19:30.641 E/GrpcClient: RegisterParty failed after 2 attempts 17:19:30.643 D/TssRepository: Starting session event subscription ← 还是执行了! -
StreamManager 日志完全缺失
[MISSING] StreamManager: Starting event stream for partyId=... -
双重连接导致 Channel shutdown
UNAVAILABLE: Channel shutdown invoked
为什么会失败:
- StreamManager 的实现有 bug
- callback 机制不如直接 Flow.collect 可靠
- init 块的监听可能导致时序问题
- 增加了复杂度,引入了新的失败点
🔄 阶段4:回退尝试(bfbd062e)
Commit bfbd062e (2026-01-27 01:34:16) ⚠️ 部分回退
标题: "refactor(android): 回归简单可靠的流管理架构"
改动内容:
- ✅ 删除 StreamManager.kt
- ✅ 删除 init 块监听
- ✅ 恢复 jobManager.launch 模式
- ✅ 添加 registerParty 错误检查(新增,好的改进)
- ✅ 保留 Keep-Alive 配置
- ✅ 保留网络监听
- ⚠️ 添加了 Flow.retryWhen(这是新增的,不在 41e7eed2)
与 41e7eed2 的差异:
// 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 错误检查(好的):
+ val registerResult = grpcClient.registerParty(partyId, "temporary", "1.0.0")
+ if (registerResult.isFailure) {
+ throw registerResult.exceptionOrNull() ?: Exception("Failed to register party")
+ }
但也添加了 retryWhen(不确定):
+ .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(失败但继续):
grpcClient.registerParty(partyId, "temporary", "1.0.0") // 失败但继续
startSessionEventSubscription() // 还是会执行
bfbd062e(失败就停止):
val registerResult = grpcClient.registerParty(partyId, "temporary", "1.0.0")
if (registerResult.isFailure) {
throw ... // ← 直接抛异常,后续不执行
}
startSessionEventSubscription() // 不会执行
问题: 如果 registerParty 失败,现在会直接停止,不会继续订阅事件。 但: 这应该是对的行为!如果注册失败,继续也没意义。
2. retryWhen 可能导致重复订阅 ⚠️
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 的改动是否影响了基本功能。
测试建议
要验证的点:
-
RegisterParty 是否成功
看日志: "Party registered successfully" -
事件订阅是否启动
看日志: "Starting session event subscription for partyId: xxx" -
retryWhen 是否影响正常流
看日志: 是否有 "Event stream failed" 警告 -
GrpcClient 的改动是否有问题
对比 41e7eed2 和 bfbd062e 的 GrpcClient.kt
修复方案
选项A:完全回退到 41e7eed2 ✅
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,保留其他改进 ✅
// 恢复为 41e7eed2 的简单版本
jobManager.launch(JOB_SESSION_EVENT) {
grpcClient.subscribeSessionEvents(effectivePartyId).collect { event ->
// 处理事件
}
}
优点: 保留 Keep-Alive 和 registerParty 检查
缺点: 失去自动重连能力(但 41e7eed2 也没有)
选项C:测试当前版本,看具体哪里失败 ✅
用 build-install-debug.bat 测试,查看具体日志。
总结
24小时内改了什么:
003871ad: 添加 markPartyReady 重试(有小bug)41e7eed2: 修复 repeat 循环 bug ✅ 工作7b957114: 引入 StreamManager ❌ 破坏性改动bfbd062e: 删除 StreamManager ⚠️ 部分回退
为什么功能失败:
7b957114引入的 StreamManager 有严重 bugbfbd062e的回退不彻底:- 添加了 retryWhen(41e7eed2 没有)
- 添加了 registerParty 检查(可能导致提前停止)
- 没有回退 GrpcClient.kt 的改动
下一步:
立即测试当前版本,或完全回退到 41e7eed2