-
Notifications
You must be signed in to change notification settings - Fork 22
refactor: move NetworkStack to WireNetwork for re-use - WPB-17719 #3257
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
base: develop
Are you sure you want to change the base?
refactor: move NetworkStack to WireNetwork for re-use - WPB-17719 #3257
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.
Moved to WireNetwork
@@ -55,12 +56,13 @@ class DetermineAuthMethodComponent: Component<DetermineAuthMethodComponentDepend | |||
email: String?, | |||
canCreateAccount: Bool, | |||
didDetectDomainConflict: Bool, | |||
backendInfo: BackendInfo |
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.
Here and elsewhere you'll see that BackendInfo
has been replaced by BackendEnvironment2
(which will be renamed to BackendEnvironment
), which will be the sole environment model going forward.
public typealias WireAuthenticationBackendEnvironment = WireAuthenticationAPI.WireAuthenticationBackendEnvironment | ||
public typealias BackendEnvironmentType = WireAuthenticationAPI.BackendEnvironmentType | ||
public typealias BackendConfig = WireAuthenticationAPI.BackendConfig | ||
public typealias Endpoints = WireAuthenticationAPI.Endpoints | ||
public typealias ProxySettings = WireAuthenticationAPI.UnresolvedProxySettings | ||
public typealias TrustData = WireAuthenticationAPI.TrustData | ||
public typealias BackendMetadata = WireAuthenticationAPI.BackendMetadata |
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.
These were all old models that are no longer needed, replaced by BackendEnvironment2
} | ||
|
||
var proxyServer: String { | ||
backendInfo.backendConfig.endpoints.backendURL.absoluteString |
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 was wrong (it's the backend rest api endpoint), I believe it should be the proxy host (right @KaterinaWire ?)
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.
These and the following deleted snapshots don't have a corresponding test, so the snapshots have been deleted.
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.
These snapshot tests changed because I fixed a typo (there were some other tests that needed re-recording for non visible changes)
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.
The client session component current holds a lot of the "new stack" for the user session. The changes here are:
- we don't inject small pieces like network service, api version, etc...
- instead we inject in what is needed which is
AuthenticatedRESTAPI
(see later in the pull request) to provide the api clients.
public lazy var accountsAPI: some AccountsAPI = authenticatedRESTAPI.accountsAPI() | ||
public lazy var conversationsAPI: some ConversationsAPI = authenticatedRESTAPI.conversationsAPI() |
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.
These two are public because they're still needed outside this component. There was some code in UI project that creates api clients to make use cases. For now I made these public, but in the future the UI project shouldn't be concerned with api clients.
@@ -316,7 +260,7 @@ public final class ClientSessionComponent { | |||
store: userLocalStore | |||
) | |||
|
|||
private lazy var pullSelfUserClientsSync = PullSelfUserClientsSync( | |||
public lazy var pullSelfUserClientsSync = PullSelfUserClientsSync( |
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.
Similar to the last comment, it's public because there's some other target that is using it.
private let backendEnvironment: WireNetwork.BackendEnvironment | ||
private let minTLSVersion: WireNetwork.TLSVersion | ||
private let apiVersion: WireNetwork.APIVersion |
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.
We not just inject a NetworkStack
which encapsulate all the set up.
) async throws -> ClientSessionComponent { | ||
let authenticatedRESTAPI = try await networkStack.authenticatedRESTAPI( | ||
userID: selfUserID, | ||
clientID: clientID, | ||
cookieEncryptionKey: UserDefaults.cookiesKey() | ||
) |
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 needs to be async
now, but I think it's only temporary. Deterministic session loading will ensure that the network stack is fully set up (which is async
) before we have a user session.
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 is the entry point for the new NSE. I've moved some of the dependencies around (e.g up to higher components and passing through to children via Needle).
|
||
public extension BackendEnvironment2 { | ||
|
||
init(_ legacyEnvironment: WireTransport.BackendEnvironment) { |
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.
All these mappings are temporary until we implement multibackend support and remove the legacy environments).
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 was dead
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.
Moved to WireNetworkInterface
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.
Moved to WireNetworkInterface
clientID: clientID, | ||
cookieStorage: cookieStorage, | ||
networkService: networkServices.rest, | ||
onAuthenticationFailure: {} // TODO: network stack should bubble this up |
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.
issue: still TODO
import WireLogging | ||
import WireNetworkInterface | ||
|
||
// TODO: doc |
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.
issue: Still TODO
|
||
} | ||
|
||
// TODO: move to network service |
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.
issue: still TODO
// along with this program. If not, see http://www.gnu.org/licenses/. | ||
// | ||
|
||
public struct AuthenticatedRESTAPI { |
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 is a factory for all api clients that need an APIService
(which requires an AuthenticationManager
). It's an async throws
operation to create this factory because the api version needs to be resolved.
But once we have it we can create api clients when needed.
@@ -16,18 +16,14 @@ | |||
// along with this program. If not, see http://www.gnu.org/licenses/. | |||
// | |||
|
|||
import Foundation | |||
public struct UnauthenticatedRESTAPI: Sendable { |
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.
Similar to AuthenticatedRESTAPI
but doesn't need an api service, just a network service...
|
||
extension ProxySettings { | ||
|
||
func proxyDictionary() -> [AnyHashable: Any] { |
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.
Moved from the model definition, it's only needed here.
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.
Moved from WireAuthentication.
|
||
private extension BackendEnvironment2 { | ||
|
||
init(_ legacyEnvironment: WireTransport.BackendEnvironment) { |
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 is some duplication, but we'll remove when the legacy environment is retired when multibackend support is added.
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.
minor suggestion: Add TODO with ticket in order not forget remove it here
asyncStreamEnabled: selfUserClient.asyncStreamCapable | ||
) | ||
} catch { | ||
fatalError("failed to set up sync agent: \(error)") |
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.
issue: intending to address this with deterministic session loading, but maybe need to an intermediate solution. For instance, what happens if there's no network? Will this fatalError?
…rk-wpb-17719 # Conflicts: # WireAuthentication/Tests/WireAuthenticationUITests/Resources/ReferenceImages/PersonalAccountCreationViewTests/testDynamicTypeVariants.xxxLarge.png # WireNetwork/Sources/WireNetwork/Models/Backend/BackendEnvironment2.swift # WireNetwork/Sources/WireNetworkInterface/Models/PinnedKey.swift # wire-ios-sync-engine/Source/SessionManager/SessionFactories.swift # wire-ios-sync-engine/Source/UserSession/ZMUserSession/ZMUserSession.swift
Test Results 4 files 449 suites 5m 6s ⏱️ For more details on these failures, see this check. Results for commit ba33885. |
Datadog ReportBranch report: ❌ 6 Failed (0 Known Flaky), 3138 Passed, 27 Skipped, 2m 6.64s Total Time ❌ Failed Tests (6)
|
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.
Great work! Left couple of comments
let authenticationAPI = try await networkStack | ||
.unauthenticatedRESTAPI() | ||
.authenticationAPI() |
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.
issue: this looks odd, is it really needed unauthenticatedRESTAPI
to make authenticationAPI
? usually it's either authenticated client or unauthenticated, and you don't need one to create another.
And from client side if authenticated
client needed, I'd hide unauthenticated
detail to implementation. Not need for client to know that
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.
ah yes the naming is confusing... on one hand we have unauthenticatedRESTAPI
as a container of api clients that don't need an authentication cookie or access token... i.e to make unauthenticated requests. One such api client is AuthenticationAPI
that is used to login or register.
Probably though this is the only 'unauthenticated' api client so maybe there is no need to have an UnauthenticatedRESTAPI
container. On the other hand, the AuthenticatedRESTAPI
container has a lot more api clients and needs a user id.
Or perhaps we can find some better names to avoid the confusion. What do you think?
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'm ok if authenticated and unauthenticated share some code and depend on each other (or one on another) in implementation part.
But not for clients, i think clients should not know about that, only thing they should care if it needs authenticated and unauthenticated client. You can hide this detail under some abstraction right?
let authenticationAPI = try await networkStack.makeAuthenticationAPI() | ||
let authenticationAPI = try await networkStack | ||
.unauthenticatedRESTAPI() | ||
.authenticationAPI() |
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: I like make
prefix, it adds clarity what it does which is being factory method. Just unauthenticatedRESTAPI()
or authenticationAPI()
is unclear to me is it wrapper, adapter or doing some side affect
|
||
private extension BackendEnvironment2 { | ||
|
||
init(_ legacyEnvironment: WireTransport.BackendEnvironment) { |
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.
minor suggestion: Add TODO with ticket in order not forget remove it here
Issue
In
WireAuthentication
we defined aNetworkStack
that is initialized with a backend environment and is handles the validation of the environment (e.g checking if proxy credentials are required, resolving backend metadata). For multibackend support, we want to do much of the same thing when setting up the user session (also for the share extension and notification extension). This PR movesNetworkStack
fromWireAuthentication
toWireNetwork
so that it can be reused. It also updates the implementation so that it can be reused more generally and updates the main app and extensions to use theNetworkStack
.Some changes include:
WireNetworkInterface
target that contains public types so other targets can depend only on types and not all the implementations ofWireNetwork
-WireNetwork.Assembly
)Testing
TODO
Checklist
[WPB-XXX]
.UI accessibility checklist
If your PR includes UI changes, please utilize this checklist: