fix(ios): recover continued processing after toggle (#1519)

This commit is contained in:
UltraGeek0102 authored and GitHub committed 2026-09-17 08:32:21 +08:00
1 parent 21702d5d46
commit 7c1447f659
2 files changed
+115 -1

No files matched your search

@@ -32,6 +32,7 @@ final class GopeedContinuedProcessingManager: NSObject {
private var expiringTasks:
[String: ExpiringTaskState] = [:]
private var taskGenerations: [String: UUID] = [:]
private var progressRecoveryTokens: [String: UUID] = [:]
private var activeTasks:
[String: BGContinuedProcessingTask] = [:]
@@ -224,6 +225,10 @@ final class GopeedContinuedProcessingManager: NSObject {
switch type {
case "task.start":
progressRecoveryTokens.removeValue(
forKey: taskID
)
beginTask(
taskID: taskID,
name: name
@@ -237,6 +242,11 @@ final class GopeedContinuedProcessingManager: NSObject {
generation: generation,
force: false
)
} else {
recoverTaskFromProgress(
taskID: taskID,
name: name
)
}
case "task.pause":
@@ -285,6 +295,72 @@ final class GopeedContinuedProcessingManager: NSObject {
}
// MARK: - Recover active task after setting changes
private func recoverTaskFromProgress(
taskID: String,
name: String
) {
guard
currentEnabledSnapshot(),
taskGenerations[taskID] == nil,
!pendingTaskIDs.contains(taskID),
activeTasks[taskID] == nil,
expiringTasks[taskID] == nil,
progressRecoveryTokens[taskID] == nil
else {
return
}
let recoveryToken = UUID()
progressRecoveryTokens[taskID] =
recoveryToken
getRuntimeStatus(
taskID: taskID
) { [weak self] runtime in
guard
let self,
self.progressRecoveryTokens[taskID]
== recoveryToken
else {
return
}
// The status request has completed. Remove the token so
// another progress event may retry if recovery is still
// necessary.
self.progressRecoveryTokens.removeValue(
forKey: taskID
)
guard
self.currentEnabledSnapshot(),
let runtime,
runtime.status == "running",
self.taskGenerations[taskID] == nil,
!self.pendingTaskIDs.contains(taskID),
self.activeTasks[taskID] == nil,
self.expiringTasks[taskID] == nil
else {
return
}
print(
"ContinuedProcessing:",
"recovering active task:",
taskID
)
self.beginTask(
taskID: taskID,
name: name
)
}
}
// MARK: - Used by Objective-C forwarder
@objc(isHandlingTaskId:)
@@ -825,6 +901,10 @@ final class GopeedContinuedProcessingManager: NSObject {
success: Bool,
finalSubtitle: String
) {
progressRecoveryTokens.removeValue(
forKey: taskID
)
taskGenerations.removeValue(
forKey: taskID
)
@@ -1063,6 +1143,7 @@ final class GopeedContinuedProcessingManager: NSObject {
pendingTaskIDs.removeAll()
expiringTasks.removeAll()
taskGenerations.removeAll()
progressRecoveryTokens.removeAll()
taskIdentifiers.removeAll()
taskNames.removeAll()
lastProgressUpdate.removeAll()
@@ -108,6 +108,39 @@ final class GopeedLiveActivityManager: NSObject {
return generation
}
private func generationForProgress(
taskID: String
) -> UUID? {
stateLock.lock()
defer { stateLock.unlock() }
guard
!suppressedTaskIDs.contains(taskID)
else {
return nil
}
if let generation =
taskGenerations[taskID] {
return generation
}
// Progress may be the first event after Continued Processing
// releases ownership. Establish a fresh lifecycle generation.
// refreshActivity still verifies that Gopeed reports the task
// as running before it can create a Live Activity.
let generation = UUID()
taskGenerations[taskID] =
generation
lastUpdateTime.removeValue(
forKey: taskID
)
return generation
}
@discardableResult
private func invalidateGeneration(
taskID: String
@@ -252,7 +285,7 @@ final class GopeedLiveActivityManager: NSObject {
case "task.progress":
guard
let generation =
currentGeneration(
generationForProgress(
taskID: taskID
)
else {