-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resolve location selection against remote locations #764
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think direction is ok for helping us prevent issues, and I think this direction is great... but this is not recovery. Are we planning to follow up with proper recovery from failed registration / connection attempts?
PS: Just being extra cautious here since I'm the one asking for recovery - if we do add recovery, let's do a follow up PR to avoid this becoming huge / neverending etc. I'm happy to keep things separated.
@@ -1041,9 +993,6 @@ open class PacketTunnelProvider: NEPacketTunnelProvider { | |||
} | |||
|
|||
settings.selectedServer = .endpoint(serverName) | |||
if case .connected = connectionStatus { | |||
try? await updateTunnelConfiguration(environment: settings.selectedEnvironment, serverSelectionMethod: .preferredServer(serverName: serverName), reassert: true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is actually changing behaviour. Why is it no longer necessary to update the tunnel configuration when the server selection changes?
func sanitizedServerSelectionMethod() async -> NetworkProtectionServerSelectionMethod | ||
} | ||
|
||
public final class VPNServerSelectionSanitizer: VPNServerSelectionSanitizing { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few comments here:
- Let's add unit tests to cover this class in its entirety.
- The name of this class sounds off to me. This does more than just sanitize the selection - it effectively manages the entire selection logic (locations vs servers in settings). Additionally when referencing this in the init parameter below (for
PacketTunnelProvider
) the instance is namedserverSelection
, which makes me think you agree. Why not name this something more generic likeVPNServerSelector
orVPNServerSelectionResolver
. - To further expand on point 2, I really think that to the
PacketTunnelProvider
whether this does sanitization or not is an implementation detail - what matters is that this class provides a server / location to connect to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the naming here gave me a lot of trouble. So just decided to open it up to get opinions. Thanks for the input.
case .setSelectedServer(let selectedServer): | ||
let serverSelectionMethod: NetworkProtectionServerSelectionMethod | ||
|
||
switch selectedServer { | ||
case .automatic: | ||
serverSelectionMethod = .automatic | ||
case .endpoint(let serverName): | ||
serverSelectionMethod = .preferredServer(serverName: serverName) | ||
} | ||
|
||
Task { @MainActor in | ||
if case .connected = connectionStatus { | ||
try? await updateTunnelConfiguration(environment: settings.selectedEnvironment, serverSelectionMethod: serverSelectionMethod, reassert: true) | ||
} | ||
completionHandler?(nil) | ||
} | ||
case .setSelectedLocation(let selectedLocation): | ||
let serverSelectionMethod: NetworkProtectionServerSelectionMethod | ||
|
||
switch selectedLocation { | ||
case .nearest: | ||
serverSelectionMethod = .automatic | ||
case .location(let location): | ||
serverSelectionMethod = .preferredLocation(location) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain why this is all going away? Admittedly I'm not looking to deeply into this and opting to ask as I want to avoid making (mistaken) assumptions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes sure. It’s essentially extracting this logic into the… class that has yet to be named ;). Let’s go with ServerSelector
. I’ve been trying to avoid adding too much more logic to the PacketTunnelProvider, but this selection logic seemed closely related to the responsibilities of the ServerSelector
. The extraction should allow it to all be unit tested too which I’ll do before moving this PR out of draft.
serverSelectionMethod = .preferredLocation(location) | ||
} | ||
|
||
case .setSelectedServer, .setSelectedLocation: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that this is now handling both server selection and location selection cases.
@diegoreymendez I agree about this not fully handling recovery. This however, does add some improvement to the robustness of the location / server selection logic and I’m trying to go for incremental improvements. However, recovering from a failed …again though, however, I’m also not 100% sure if this is the right approach or whether the location fallback logic should not be pre-emptive as it currently is, but a reaction of a railed register request. |
* main: Replace unowned reference with weak one (#832) Removes VPN waitlist and beta code (#801) Add `survey` action and Privacy Pro attributes (#826) Autofill engagement KPIs for pixel reporting (#830) Bump C-S-S to 5.17.0 (#828) ensure bookmarks can be shown in top hits (#818) Subscription refactoring (#815)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to see unit tests to cover different scenarios. Left some suggestions to improve code readability.
self.vpnSettings = vpnSettings | ||
} | ||
|
||
public func resolvedServerSelectionMethod() async -> NetworkProtectionServerSelectionMethod { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: Include the server selection fallback logic in a comment to make it more readable.
The VPN geoswitching logic currently doesn’t handle the case that a location becomes unavailable. We should fall back to the country, if a city isn’t available, or nearest if the country isn’t available.
break | ||
case .endpoint(let string): | ||
// Selecting a specific server will override locations setting | ||
// Only available in debug |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: Enforce this logic in the code (e.g. guarding .setSelectedServer(.endpoint(String))
inside ALPHA || DEBUG
)
This PR has been inactive for more than 7 days and will be automatically closed 7 days from now. |
This PR has been closed after 14 days of inactivity. Feel free to reopen it if you plan to continue working on it or have further discussions. |
Please review the release process for BrowserServicesKit here.
Required:
Task/Issue URL: https://app.asana.com/0/1203137811378537/1206773442486707/f
iOS PR: duckduckgo/iOS#2688
macOS PR: duckduckgo/macos-browser#2805
What kind of version bump will this require?: Major
Description:
The VPN geoswitching logic currently doesn’t handle the case that a location becomes unavailable. We should fall back to the country, if a city isn’t available, or nearest if the country isn’t available.
Steps to test this PR:
See platform PRs
OS Testing:
Internal references:
Software Engineering Expectations
Technical Design Template