mirror of
https://github.com/shadowsocks/ShadowsocksX-NG.git
synced 2026-10-28 21:23:44 +00:00
refactor(catalog): syncStatus 收敛单一事实源,workflow 只留透传读面
协调器退掉 @Published 与 ObservableObject:syncStatus 存储与发布单点在 协调器(写后经 syncStatusChanges 通知,didChange 语义);CatalogWorkflow 的 runtimeSync 从第二份 @Published 拷贝改为 computed 透传 + 变化通道 透传。App 侧本就无视图消费 runtimeSync,目录观察者不再被每次提交徒劳 失效;测试的轮询读面不变。
This commit is contained in:
@@ -89,9 +89,13 @@ protocol CatalogRuntimeSyncing: AnyObject {
|
||||
/// 或启动耗时阻塞。每次提交递增代次:旧代次自然结束,但不得覆盖最新代次的
|
||||
/// 最终状态;没有自动重试,后续提交、显式激活或启动代理会发起新的同步尝试。
|
||||
@MainActor
|
||||
final class CatalogCommitCoordinator: ObservableObject {
|
||||
/// 最新提交的运行时收敛阶段(结构化;呈现由上层决定)。
|
||||
@Published private(set) var syncStatus: RuntimeSyncStatus = .idle
|
||||
final class CatalogCommitCoordinator {
|
||||
/// 最新提交的运行时收敛阶段(结构化;呈现由上层决定)。存储与发布单点
|
||||
/// 在本类:写后经 `syncStatusChanges`(didChange 语义)通知;目录工作流
|
||||
/// 只透传读面,不再挂第二份 `@Published`。
|
||||
private(set) var syncStatus: RuntimeSyncStatus = .idle
|
||||
/// 收敛阶段变化通道(didChange 语义,值即当前阶段)。
|
||||
let syncStatusChanges = PassthroughSubject<RuntimeSyncStatus, Never>()
|
||||
|
||||
let fileStore: CatalogFileStore
|
||||
private let runtime: CatalogRuntimeSyncing
|
||||
@@ -159,18 +163,24 @@ final class CatalogCommitCoordinator: ObservableObject {
|
||||
generation += 1
|
||||
let generation = generation
|
||||
guard runtime.hasActiveTarget else {
|
||||
syncStatus = .idle
|
||||
setSyncStatus(.idle)
|
||||
return
|
||||
}
|
||||
syncStatus = .syncing(generation: generation)
|
||||
setSyncStatus(.syncing(generation: generation))
|
||||
Task { @MainActor [weak self] in
|
||||
guard let self, self.generation == generation else { return }
|
||||
let outcome = await self.runtime.converge(to: snapshot)
|
||||
guard !Task.isCancelled, self.generation == generation else { return }
|
||||
self.syncStatus = .finished(generation: generation, outcome: outcome)
|
||||
self.setSyncStatus(.finished(generation: generation, outcome: outcome))
|
||||
}
|
||||
}
|
||||
|
||||
/// 写入与通知的唯一口径:先落值后发值(didChange 语义)。
|
||||
private func setSyncStatus(_ status: RuntimeSyncStatus) {
|
||||
syncStatus = status
|
||||
syncStatusChanges.send(status)
|
||||
}
|
||||
|
||||
/// 磁盘读取的容错口径与首次加载一致:损坏文档回退全新空文档,等待
|
||||
/// 用户经由导入/设置路径修复。
|
||||
private static func loadCommitted(
|
||||
|
||||
@@ -27,8 +27,16 @@ final class CatalogWorkflow: ObservableObject {
|
||||
/// outcome;持久化目录只保存安全的 typed failure facts。
|
||||
@Published private(set) var subscriptionRefreshFailures:
|
||||
[NodeID: SubscriptionRefreshFailureResult] = [:]
|
||||
/// 最近一次提交的运行时收敛阶段(与目录提交成功分离,story 38)。
|
||||
@Published private(set) var runtimeSync: RuntimeSyncStatus
|
||||
/// 最近一次提交的运行时收敛阶段(与目录提交成功分离,story 38)。存储与
|
||||
/// 发布单点在提交协调器,此处只透传读面;需要实时更新的表面订阅
|
||||
/// `runtimeSyncChanges`(`.onReceive` 消费),不经本类 objectWillChange——
|
||||
/// App 侧目前无视图消费者,避免每次提交徒劳失效全部目录观察者。
|
||||
var runtimeSync: RuntimeSyncStatus { dependencies.coordinator.syncStatus }
|
||||
|
||||
/// 收敛阶段变化通道(didChange 语义,值即当前阶段)。
|
||||
var runtimeSyncChanges: AnyPublisher<RuntimeSyncStatus, Never> {
|
||||
dependencies.coordinator.syncStatusChanges.eraseToAnyPublisher()
|
||||
}
|
||||
/// Legacy 快照发现与一次性完成标记。
|
||||
@Published private(set) var legacyImportState = LegacyImportAvailability(
|
||||
snapshotFound: false, completed: false)
|
||||
@@ -53,8 +61,6 @@ final class CatalogWorkflow: ObservableObject {
|
||||
subscriptions = Self.subscriptionSummaries(
|
||||
coordinator.committedSubscriptions, catalog: coordinator.committedCatalog,
|
||||
credentials: dependencies.credentials)
|
||||
runtimeSync = coordinator.syncStatus
|
||||
coordinator.$syncStatus.assign(to: &$runtimeSync)
|
||||
refreshLegacyImportState()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user