]> git.ipfire.org Git - thirdparty/wireguard-apple.git/commitdiff
UI: pause VPN configurations observer while adding or removing multiple tunnels
authorAndrej Mihajlov <and@mullvad.net>
Mon, 21 Dec 2020 12:46:55 +0000 (13:46 +0100)
committerJason A. Donenfeld <Jason@zx2c4.com>
Tue, 22 Dec 2020 11:47:02 +0000 (12:47 +0100)
Signed-off-by: Andrej Mihajlov <and@mullvad.net>
Sources/WireGuardApp/Tunnel/TunnelsManager.swift

index 93aa38468ef9cf38bdb27f65099ae824a452365d..61fe0d99d2e235a1b99c762e80ec0bd452dd9d75 100644 (file)
@@ -169,7 +169,20 @@ class TunnelsManager {
     }
 
     func addMultiple(tunnelConfigurations: [TunnelConfiguration], completionHandler: @escaping (UInt, TunnelsManagerError?) -> Void) {
-        addMultiple(tunnelConfigurations: ArraySlice(tunnelConfigurations), numberSuccessful: 0, lastError: nil, completionHandler: completionHandler)
+        // Temporarily pause observation of changes to VPN configurations to prevent the feedback
+        // loop that causes `reload()` to be called on each newly added tunnel, which significantly
+        // impacts performance.
+        configurationsObservationToken = nil
+
+        self.addMultiple(tunnelConfigurations: ArraySlice(tunnelConfigurations), numberSuccessful: 0, lastError: nil) { [weak self] numSucceeded, error in
+            completionHandler(numSucceeded, error)
+
+            // Restart observation of changes to VPN configrations.
+            self?.startObservingTunnelConfigurations()
+
+            // Force reload all configurations to make sure that all tunnels are up to date.
+            self?.reload()
+        }
     }
 
     private func addMultiple(tunnelConfigurations: ArraySlice<TunnelConfiguration>, numberSuccessful: UInt, lastError: TunnelsManagerError?, completionHandler: @escaping (UInt, TunnelsManagerError?) -> Void) {
@@ -296,7 +309,20 @@ class TunnelsManager {
     }
 
     func removeMultiple(tunnels: [TunnelContainer], completionHandler: @escaping (TunnelsManagerError?) -> Void) {
-        removeMultiple(tunnels: ArraySlice(tunnels), completionHandler: completionHandler)
+        // Temporarily pause observation of changes to VPN configurations to prevent the feedback
+        // loop that causes `reload()` to be called for each removed tunnel, which significantly
+        // impacts performance.
+        configurationsObservationToken = nil
+
+        removeMultiple(tunnels: ArraySlice(tunnels)) { [weak self] error in
+            completionHandler(error)
+
+            // Restart observation of changes to VPN configrations.
+            self?.startObservingTunnelConfigurations()
+
+            // Force reload all configurations to make sure that all tunnels are up to date.
+            self?.reload()
+        }
     }
 
     private func removeMultiple(tunnels: ArraySlice<TunnelContainer>, completionHandler: @escaping (TunnelsManagerError?) -> Void) {