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

10 KiB
Raw Blame History

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"

改动内容:

// 添加 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()
+             }
+     }
+ }

导致的问题:

  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 的差异:

// 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.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

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小时内改了什么

  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