Skip to content
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

Use the streaming HttpEngine by default on Apple #5671

Merged
merged 3 commits into from Mar 1, 2024

Conversation

BoD
Copy link
Contributor

@BoD BoD commented Mar 1, 2024

Resolves #5659

@BoD BoD requested a review from martinbonnin as a code owner March 1, 2024 08:39
Copy link

netlify bot commented Mar 1, 2024

Deploy Preview for apollo-android-docs canceled.

Name Link
🔨 Latest commit fe81a37
🔍 Latest deploy log https://app.netlify.com/sites/apollo-android-docs/deploys/65e1cc87f32ae000081719ba

Comment on lines 315 to 320
if (nsUrlSession == null) nsUrlSession = NSURLSession.sessionWithConfiguration(
configuration = NSURLSessionConfiguration.defaultSessionConfiguration(),
delegate = delegate,
delegateQueue = null
)
return nsUrlSession!!.dataTaskWithRequest(request)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is prone to race conditions and also surprising because delegate would only be taken into account for the first call. What about

fun interface DataTaskFactory {
  fun dataTask(request: NSURLRequest): NSURLSessionDataTask
}

class DefaultHttpEngine(
    private val timeoutMillis: Long = 60_000,
    private val dataTaskFactory: (NSURLSessionDataDelegateProtocol) -> DataTaskFactory,
) : HttpEngine {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also more general comment about fun interface. We don't have many in the codebase and I think I'd prefer not adding too many. Regular interfaces are probably easier to evolve if we need to

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah but wait, we need to control the delegate so looks like we need a factory of factory instead 🙈 . I've edited my initial comment

*/
@ApolloExperimental
class StreamingNSURLSessionHttpEngine(
actual class DefaultHttpEngine(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remove the expect/actual classes to use top level constructor functions instead? (Can be made in a separate PR)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do it in the next PR (also to implement Closeable to replace dispose())

Comment on lines 318 to 332
interface DataTaskFactory {
fun dataTask(request: NSURLRequest): NSURLSessionDataTask
}

private class DefaultDataTaskFactory(delegate: NSURLSessionDataDelegateProtocol) : DataTaskFactory {
private val nsUrlSession = NSURLSession.sessionWithConfiguration(
configuration = NSURLSessionConfiguration.defaultSessionConfiguration(),
delegate = delegate,
delegateQueue = null
)

override fun dataTask(request: NSURLRequest): NSURLSessionDataTask {
return nsUrlSession.dataTaskWithRequest(request)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this more, do we even need DataTaskFactory? Can't we "just" have

actual class DefaultHttpEngine : HttpEngine {
  constructor(
      timeoutMillis: Long = 60_000,
      configuration: NSURLSessionConfiguration?
  ) {

What is the use case for changing anythign else than the configuration?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want to allow people to have a global NSURLSession for their app, like we do on the JVM with constructors that accept a OkHttpClient or Call.Factory.

But honestly it's hard to tell if it's actually useful without being an iOS dev 😅

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want to allow people to have a global NSURLSession for their app, like we do on the JVM with constructors that accept a OkHttpClient or Call.Factory.

Given we force the delegate, I don't think the NSURLSession can be reused by any other parts of the app so we might as well own it (also we're talking about closing it ourselves so if it is shared we def. don't want to close it and we'd have to refcount and what not)

Also looks like the iOS client allocates its own URLsession: https://github.com/apollographql/apollo-ios/blob/b434fb904b4695bcc84e83ca1cac132321bf5435/Sources/Apollo/URLSessionClient.swift#L64

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good points, yeah that sounds about right. Simply passing a NSURLSessionConfiguration is definitely a welcome simplification 👍

@BoD BoD merged commit f2dc563 into main Mar 1, 2024
9 checks passed
@BoD BoD deleted the use-apple-streaming-http-engine branch March 1, 2024 14:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use StreamingNSURLSessionHttpEngine by default on Apple
2 participants