add IDLE monitoring to SyncCoordinator: start/stop with capability check
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,7 +13,10 @@ public final class SyncCoordinator {
|
||||
private let store: MailStore
|
||||
private let actionQueue: ActionQueue?
|
||||
private let taskStore: TaskStore?
|
||||
private let credentials: Credentials?
|
||||
private var syncTask: Task<Void, Never>?
|
||||
private var idleClient: IMAPIdleClient?
|
||||
private var idleActive = false
|
||||
|
||||
public private(set) var syncState: SyncState = .idle
|
||||
private var eventHandlers: [(SyncEvent) -> Void] = []
|
||||
@@ -23,13 +26,15 @@ public final class SyncCoordinator {
|
||||
imapClient: any IMAPClientProtocol,
|
||||
store: MailStore,
|
||||
actionQueue: ActionQueue? = nil,
|
||||
taskStore: TaskStore? = nil
|
||||
taskStore: TaskStore? = nil,
|
||||
credentials: Credentials? = nil
|
||||
) {
|
||||
self.accountConfig = accountConfig
|
||||
self.imapClient = imapClient
|
||||
self.store = store
|
||||
self.actionQueue = actionQueue
|
||||
self.taskStore = taskStore
|
||||
self.credentials = credentials
|
||||
}
|
||||
|
||||
public func onEvent(_ handler: @escaping (SyncEvent) -> Void) {
|
||||
@@ -286,6 +291,49 @@ public final class SyncCoordinator {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - IMAP IDLE
|
||||
|
||||
/// Check server capabilities and start IDLE monitoring if supported.
|
||||
/// Must be called after at least one successful sync (so capabilities are cached).
|
||||
public func startIdleMonitoring() async {
|
||||
guard let credentials else {
|
||||
print("[SyncCoordinator] No credentials provided, cannot start IDLE")
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
let caps = try await imapClient.capabilities()
|
||||
guard caps.contains("IDLE") else {
|
||||
print("[SyncCoordinator] Server does not support IDLE, using periodic sync only")
|
||||
return
|
||||
}
|
||||
|
||||
let client = IMAPIdleClient(
|
||||
host: accountConfig.imapHost,
|
||||
port: accountConfig.imapPort,
|
||||
credentials: credentials
|
||||
)
|
||||
|
||||
idleClient = client
|
||||
idleActive = true
|
||||
|
||||
try await client.startMonitoring { [weak self] in
|
||||
Task { @MainActor [weak self] in
|
||||
try? await self?.syncNow()
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
print("[SyncCoordinator] Failed to start IDLE monitoring: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
/// Stop IDLE monitoring and clean up.
|
||||
public func stopIdleMonitoring() async {
|
||||
idleActive = false
|
||||
await idleClient?.stopMonitoring()
|
||||
idleClient = nil
|
||||
}
|
||||
|
||||
// MARK: - Periodic Sync
|
||||
|
||||
public func startPeriodicSync(interval: Duration = .seconds(300)) {
|
||||
|
||||
Reference in New Issue
Block a user