rwadurian/backend/mpc-system/services/service-party-android/24H_TIMELINE_ANALYSIS.md

387 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 24小时改动时间线分析
## 用户质疑
> "那你回顾一下这24小时内都在改什么为什么导致原来的co-keygen,keygen,co-sign,sign功能失败了"
## 完整时间线
### ✅ 阶段1工作的版本起点
**最后一个完全工作的commit**: 在 003871ad 之前
**状态**:
- ✅ co-keygen 正常
- ✅ keygen 正常
- ✅ co-sign 正常
- ✅ sign 正常
---
### ⚠️ 阶段2Bug修复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.kt216 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 的回退不彻底**:
- 添加了 retryWhen41e7eed2 没有)
- 添加了 registerParty 检查(可能导致提前停止)
- 没有回退 GrpcClient.kt 的改动
### 下一步:
**立即测试当前版本,或完全回退到 41e7eed2**