From 373bb2ae99f0997a03561fad735d73a479e14c4e Mon Sep 17 00:00:00 2001 From: Andrej Mihajlov Date: Mon, 21 Dec 2020 13:46:55 +0100 Subject: [PATCH] UI: pause VPN configurations observer while adding or removing multiple tunnels Signed-off-by: Andrej Mihajlov --- .../WireGuardApp/Tunnel/TunnelsManager.swift | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/Sources/WireGuardApp/Tunnel/TunnelsManager.swift b/Sources/WireGuardApp/Tunnel/TunnelsManager.swift index 93aa384..61fe0d9 100644 --- a/Sources/WireGuardApp/Tunnel/TunnelsManager.swift +++ b/Sources/WireGuardApp/Tunnel/TunnelsManager.swift @@ -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, 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, completionHandler: @escaping (TunnelsManagerError?) -> Void) {