From ec54877140eb6fea370b1c3f4b3addf4951482ef Mon Sep 17 00:00:00 2001 From: jack Date: Wed, 14 Jan 2026 10:54:23 -1000 Subject: [PATCH] Remove dormant wake attempt on Tor foreground restart Arti's dormant/wake FFI functions are no-op stubs that don't actually implement dormant mode. The app was wasting 2.5-12 seconds trying to wake from a dormant state that doesn't exist before falling back to a full restart. This change: - Removes wakeFromDormant() call and function - Simplifies goDormantOnBackground() to just mark state as not ready - Goes straight to restartArti() on foreground, eliminating the delay Co-Authored-By: Claude Opus 4.5 --- .../Extensions/ChatViewModel+Tor.swift | 2 +- localPackages/Arti/Sources/TorManager.swift | 68 +++---------------- 2 files changed, 10 insertions(+), 60 deletions(-) diff --git a/bitchat/ViewModels/Extensions/ChatViewModel+Tor.swift b/bitchat/ViewModels/Extensions/ChatViewModel+Tor.swift index 1945b981..443849db 100644 --- a/bitchat/ViewModels/Extensions/ChatViewModel+Tor.swift +++ b/bitchat/ViewModels/Extensions/ChatViewModel+Tor.swift @@ -24,7 +24,7 @@ extension ChatViewModel { } } } - + @objc func handleTorWillRestart() { Task { @MainActor in self.torRestartPending = true diff --git a/localPackages/Arti/Sources/TorManager.swift b/localPackages/Arti/Sources/TorManager.swift index 24d62d67..45958b59 100644 --- a/localPackages/Arti/Sources/TorManager.swift +++ b/localPackages/Arti/Sources/TorManager.swift @@ -290,6 +290,7 @@ public final class TorManager: ObservableObject { public func ensureRunningOnForeground() { if !allowAutoStart { return } + SecureLogger.debug("TorManager: ensureRunningOnForeground() started", category: .session) Task.detached(priority: .userInitiated) { [weak self] in guard let self = self else { return } let claimed: Bool = await MainActor.run { @@ -299,12 +300,6 @@ public final class TorManager: ObservableObject { } if !claimed { return } - // Try to wake if dormant - if await self.wakeFromDormant() { - await MainActor.run { self.restarting = false } - return - } - // Check if already ready let alreadyReady = await MainActor.run { self.isReady } if alreadyReady { @@ -312,41 +307,21 @@ public final class TorManager: ObservableObject { return } - // Restart + // Arti doesn't support dormant/wake (it's a no-op stub), so always do full restart await self.restartArti() await MainActor.run { self.restarting = false } } } public func goDormantOnBackground() { + // Arti doesn't support real dormant mode, so just mark as not ready. + // iOS will suspend the runtime anyway. On foreground we do a full restart. + // Clear isStarting so foreground recovery can proceed if bootstrap was interrupted. SecureLogger.debug("TorManager: goDormantOnBackground() called", category: .session) - Task.detached { [weak self] in - guard let self = self else { return } - let result = arti_go_dormant() - if result == 0 { - SecureLogger.info("TorManager: signalled DORMANT", category: .session) - await MainActor.run { - self.isDormant = true - self.isReady = false - self.socksReady = false - self.isStarting = false - } - } else { - // Dormant not supported, do full shutdown - SecureLogger.warning("TorManager: DORMANT failed; shutting down", category: .session) - _ = arti_stop() - await MainActor.run { - self.isDormant = false - self.isReady = false - self.socksReady = false - self.bootstrapProgress = 0 - self.bootstrapSummary = "" - self.isStarting = false - self.didStart = false - self.bootstrapMonitorStarted = false - // Note: Don't clear startedAt - it will be set fresh on next start - } - } + Task { @MainActor in + self.isReady = false + self.socksReady = false + self.isStarting = false } } @@ -379,31 +354,6 @@ public final class TorManager: ObservableObject { } } - private func wakeFromDormant() async -> Bool { - let wasDormant = await MainActor.run { self.isDormant } - if !wasDormant { return false } - - let result = arti_wake() - if result != 0 { return false } - - await MainActor.run { - self.isDormant = false - self.isStarting = true - self.socksReady = false - } - - let ready = await waitForSocksReady(timeout: 12.0) - await MainActor.run { - self.socksReady = ready - self.isStarting = !ready - } - - if ready { - SecureLogger.info("TorManager: woke from dormant", category: .session) - } - return ready - } - private func restartArti() async { SecureLogger.debug("TorManager: restartArti() starting", category: .session) await MainActor.run {