Conversation
保持原版 SDK 与依赖文件不变,由核心健康检查接管重连并更新连接状态。补充内置进程退出、QQ 离线及旧会话隔离处理;状态管理与最终 SDK 通知方案共用。
审查者指南本 PR 在不修改 Milky SDK 及第三方依赖的前提下,由核心接管 Milky 连接健康检查与重连,并通过会话/进程 generation 和生命周期锁隔离过期状态;同时增强故事日志缓存链接校验及上传失败降级,并补充相关回归测试。 Milky 连接健康监测与恢复时序图sequenceDiagram
participant Monitor as ConnectionMonitor
participant Core as PlatformAdapterMilky
participant API as MilkyRESTAPI
participant WS as MilkyWebSocket
participant UI as EndpointState
loop Every 3 seconds
Monitor->>API: probeMilkyHealth()
alt Health check fails
Monitor->>Core: onMilkyConnectionChange(session, false)
Core->>UI: StateDisconnected
Monitor->>WS: closeMilkyTransport(session)
else Health check succeeds
Monitor->>Core: openMilkyTransport(session)
Core->>WS: session.Open()
alt WebSocket reconnects
WS-->>Core: connection established
Core->>UI: StateConnected
else WebSocket handshake fails
Core->>UI: StateDisconnected
end
end
end
Milky 会话生命周期状态图stateDiagram-v2
[*] --> Connecting: startMilkySession()
Connecting --> Connected: finishMilkySession() and WebSocket connected
Connecting --> ConnectionFailed: openMilkyTransport() fails
Connected --> Disconnected: probeMilkyHealth() fails
Connected --> Disconnected: onMilkyBotOffline()
Disconnected --> Connected: probeMilkyHealth() succeeds and openMilkyTransport() succeeds
Disconnected --> Disconnected: REST health succeeds but WebSocket reconnect fails
Connected --> [*]: stopMilkySession()
Disconnected --> [*]: stopMilkySession()
ConnectionFailed --> [*]: stopMilkySession()
缓存故事日志 URL 校验与降级流程图flowchart TD
A[Upload log] --> B[Load cached URL and timestamps]
B --> C{Cached URL is newer than log?}
C -- No --> D[Upload updated log]
C -- Yes --> E["checkCachedLogURL()"]
E --> F{"probeCachedLogURL()"}
F -- Alive --> G[Return cached URL]
F -- Missing --> D
F -- Unknown --> D
D --> H{Upload succeeds?}
H -- Yes --> I[Save upload metadata and return new URL]
H -- No --> J["fallbackToCachedLogURL()"]
J -- Cache status unknown --> K[Return cached URL with warning]
J -- Otherwise --> L[Return upload error]
文件级变更
提示与命令与 Sourcery 交互
自定义使用体验访问你的控制面板以:
获取帮助Original review guide in EnglishReviewer's Guide本 PR 在不修改 Milky SDK 及第三方依赖的前提下,由核心接管 Milky 连接健康检查与重连,并通过会话/进程 generation 和生命周期锁隔离过期状态;同时增强故事日志缓存链接校验及上传失败降级,并补充相关回归测试。 Sequence diagram for Milky connection health monitoring and recoverysequenceDiagram
participant Monitor as ConnectionMonitor
participant Core as PlatformAdapterMilky
participant API as MilkyRESTAPI
participant WS as MilkyWebSocket
participant UI as EndpointState
loop Every 3 seconds
Monitor->>API: probeMilkyHealth()
alt Health check fails
Monitor->>Core: onMilkyConnectionChange(session, false)
Core->>UI: StateDisconnected
Monitor->>WS: closeMilkyTransport(session)
else Health check succeeds
Monitor->>Core: openMilkyTransport(session)
Core->>WS: session.Open()
alt WebSocket reconnects
WS-->>Core: connection established
Core->>UI: StateConnected
else WebSocket handshake fails
Core->>UI: StateDisconnected
end
end
end
State diagram for Milky session lifecyclestateDiagram-v2
[*] --> Connecting: startMilkySession()
Connecting --> Connected: finishMilkySession() and WebSocket connected
Connecting --> ConnectionFailed: openMilkyTransport() fails
Connected --> Disconnected: probeMilkyHealth() fails
Connected --> Disconnected: onMilkyBotOffline()
Disconnected --> Connected: probeMilkyHealth() succeeds and openMilkyTransport() succeeds
Disconnected --> Disconnected: REST health succeeds but WebSocket reconnect fails
Connected --> [*]: stopMilkySession()
Disconnected --> [*]: stopMilkySession()
ConnectionFailed --> [*]: stopMilkySession()
Flow diagram for cached story-log URL validation and fallbackflowchart TD
A[Upload log] --> B[Load cached URL and timestamps]
B --> C{Cached URL is newer than log?}
C -- No --> D[Upload updated log]
C -- Yes --> E["checkCachedLogURL()"]
E --> F{"probeCachedLogURL()"}
F -- Alive --> G[Return cached URL]
F -- Missing --> D
F -- Unknown --> D
D --> H{Upload succeeds?}
H -- Yes --> I[Save upload metadata and return new URL]
H -- No --> J["fallbackToCachedLogURL()"]
J -- Cache status unknown --> K[Return cached URL with warning]
J -- Otherwise --> L[Return upload error]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
你好——我发现了 2 个问题
AI Agent 提示词
请处理本次代码审查中的评论:
## 个别评论
### 评论 1
<location path="dice/platform_adapter_milky_helper.go" line_range="245" />
<code_context>
conn := ep.Adapter.(*PlatformAdapterMilky)
+ pa := conn
+ BuiltinMilkyClientKill(d, ep)
+ generation, done := pa.beginMilkyProcess()
doServe := func() {
- if ep.Platform == "QQ" {
</code_context>
<issue_to_address>
**问题 (bug_risk):** beginMilkyProcess 会将端点设置为 Connecting 并创建 processDone,但此后的设置失败(GetRandomFreePort、配置不受支持或 WriteFile 失败)会直接返回,而不会调用 failMilkyProcessStart 或关闭 done。账号会一直卡在 Connecting 状态,之后 BuiltinMilkyClientKill 会等待永远不会关闭的 processDone 通道,直到五秒超时。
**触发条件:** 当内嵌的 Milky 客户端在子进程启动前无法分配端口或写入配置时。
**建议修复:** 让 beginMilkyProcess 之后的每个返回路径都经过统一的启动失败清理逻辑,将连接标记为失败,并关闭或替换 processDone。
</issue_to_address>
### 评论 2
<location path="dice/platform_adapter_milky.go" line_range="160" />
<code_context>
+ log := zap.S().Named(logger.LogKeyAdapter)
+ wsGateway := strings.TrimSuffix(pa.WsGateway, "/")
+ restGateway := strings.TrimSuffix(pa.RestGateway, "/")
+ session, err := milky.New(wsGateway, restGateway, pa.Token, log.Named(logger.LogKeyAdapter))
if err != nil {
log.Errorf("Milky SDK initialization failed: %v", err)
</code_context>
<issue_to_address>
**问题 (broader_impact):** 如果 milky.New 返回初始化错误,serveMilky 会立即返回,而不会更新端点状态,也不会禁用失败的会话或以其他方式标记该会话。DoRelogin 会使端点停留在 Connecting 状态,而 SetEnable(true) 可能会继续显示之前的 Connected 状态,尽管实际上并未创建会话。
**触发条件:** 当 Milky SDK 在 New 期间拒绝已配置的网关或令牌时。
**建议修复:** 在 New 的错误路径返回前设置 StateConnectionFailed(以及适当的 Enable 值),或者让调用方一致地处理非零的 Serve 返回结果。
</issue_to_address>Sourcery 评估
需要人工审查。 有 2 个发现需要优先处理;此外,新的健康监视器以及会话/进程代际机制可能会关闭一个可用的 Milky 连接、拒绝有效的恢复,或让过时的生命周期回调使账号保持断开状态或被错误地报告为已连接;禁用 SDK 的重连路径会加剧此类竞态的影响。回滚可以移除新行为,但在错误状态生效期间发生的任何中断或漏收消息,都无法通过回滚恢复。
阻塞性发现:dice/platform_adapter_milky_helper.go:245、dice/platform_adapter_milky.go:160
Original comment in English
Hey - I've found 2 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="dice/platform_adapter_milky_helper.go" line_range="245" />
<code_context>
conn := ep.Adapter.(*PlatformAdapterMilky)
+ pa := conn
+ BuiltinMilkyClientKill(d, ep)
+ generation, done := pa.beginMilkyProcess()
doServe := func() {
- if ep.Platform == "QQ" {
</code_context>
<issue_to_address>
**issue (bug_risk):** beginMilkyProcess sets the endpoint to Connecting and creates processDone, but setup failures after this point (GetRandomFreePort, unsupported configuration, or WriteFile failure) return without calling failMilkyProcessStart or closing done. The account remains stuck in Connecting, and later BuiltinMilkyClientKill waits for the never-closed processDone channel until its five-second timeout.
**Triggers:** When an embedded Milky client cannot allocate its port or write its configuration before the child process starts.
**Suggested fix:** Route every return after beginMilkyProcess through a shared startup-failure cleanup that marks the connection failed and closes or replaces processDone.
</issue_to_address>
### Comment 2
<location path="dice/platform_adapter_milky.go" line_range="160" />
<code_context>
+ log := zap.S().Named(logger.LogKeyAdapter)
+ wsGateway := strings.TrimSuffix(pa.WsGateway, "/")
+ restGateway := strings.TrimSuffix(pa.RestGateway, "/")
+ session, err := milky.New(wsGateway, restGateway, pa.Token, log.Named(logger.LogKeyAdapter))
if err != nil {
log.Errorf("Milky SDK initialization failed: %v", err)
</code_context>
<issue_to_address>
**issue (broader_impact):** If milky.New returns an initialization error, serveMilky returns immediately without updating the endpoint state or disabling/otherwise marking the failed session. DoRelogin leaves the endpoint in Connecting, while SetEnable(true) can leave the previous Connected state visible even though no session was created.
**Triggers:** When the Milky SDK rejects the configured gateway or token during New.
**Suggested fix:** Set StateConnectionFailed (and the appropriate Enable value) before returning from the New error path, or have callers handle the nonzero Serve result consistently.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 2 findings to address first, and the new health monitor and session/process-generation machinery can close a usable Milky connection, reject a valid recovery, or let a stale lifecycle callback leave the account disconnected or falsely reported as connected; disabling the SDK's reconnect path increases the impact of such a race. Reverting removes the new behavior, but any outage or missed messages that occurred while the wrong state was active cannot be recovered by the revert.
Blocking findings: dice/platform_adapter_milky_helper.go:245, dice/platform_adapter_milky.go:160
统一清理端口分配、配置生成、目录创建和文件写入失败后的登录状态与完成通道,并隔离旧启动尝试。补充实际配置写入失败、子进程启动失败及无效网关入口的回归测试。
…Nyaa/sealdice-core into milky-disconnect-workaround
Milky 服务断开或内置 Yogurt、LagrangeV2 客户端退出后,核心没有及时更新连接状态,导致日志已经出现
connection refused,前端仍显示“已连接”。本 PR 在核心侧补充连接检测,保持原版 Milky SDK 及
go.mod、go.sum不变,无需修改或升级第三方库。主要改动:
连接监测与账号状态管理分开实现,后续 SDK 支持原生连接通知后,可以替换监测实现,保留共用的状态与进程管理逻辑。
验证:
这是轮询方案,识别掉线存在检测延迟;无法立即识别尚未产生读写错误的静默 WebSocket 故障,但是已可以基本满足状态识别的需求。
Sourcery 总结
改进 Milky 连接状态跟踪,并增强缓存日志上传功能,使其能够应对链接过期或暂时无法访问的情况。
Bug 修复:
功能增强:
测试:
Original summary in English
Sourcery 总结
改进 Milky 连接状态跟踪并增强缓存日志上传的可靠性。
Bug 修复:
增强功能:
测试:
Original summary in English
Sourcery 摘要
提高 Milky 连接状态的准确性,并增强缓存日志链接在过期和后端故障时的可靠性。
错误修复:
改进:
测试:
Original summary in English
Summary by Sourcery
Improve Milky connection state accuracy and make cached log links resilient to expiration and backend failures.
Bug Fixes:
Enhancements:
Tests:
Original summary in English