[Performance] Fix missing network traces for Swift async/await URLSession requests on iOS 16+ (#11861)#15982
[Performance] Fix missing network traces for Swift async/await URLSession requests on iOS 16+ (#11861)#15982JesusRojass wants to merge 15 commits intofirebase:mainfrom
Conversation
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces support for Swift async/await network tasks by implementing and instrumenting URLSession:didCreateTask: and URLSession:task:didFinishCollectingMetrics: delegate methods. The changes also include updates to unit tests for more deterministic failure scenarios and new tests for the async/await functionality. Feedback suggests refactoring duplicated logic in the instrumentation methods into common helper functions for improved maintainability. Additionally, it's recommended to remove > 0 checks when assigning responseSize and requestSize from NSURLSessionTaskTransactionMetrics to ensure accuracy and consistency, as these metrics are considered reliable.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces support for Swift async/await network instrumentation in Firebase Performance. It adds handling for URLSession:didCreateTask: (iOS 16+) and URLSession:task:didFinishCollectingMetrics: (iOS 10+) to capture network traces for tasks where traditional delegate callbacks might be suppressed. The changes include new helper functions, updated instrumentation logic in FPRNSURLSessionDelegateInstrument, and comprehensive unit tests to verify the new behavior and ensure no duplicate traces are created. I have no feedback to provide.
|
The machine is pleased and so am I Ready for review @visumickey |
|
@visumickey All CI/CD check should hopefully pass now! |
|
Hello there @tejasd Wondering if you could help me review this one too please! |
Discussion
Fixes #11861
Firebase Performance instruments
NSURLSessionby swizzling ObjC methods on session delegateclasses and task creation methods. This works well for traditional ObjC style request patterns
(completion handlers, delegate callbacks), but Swift async/await URLSession methods like
data(for:),download(for:),bytes(for:)are pure Swift extensions onURLSessionwithno ObjC selector, so they are invisible to method swizzling and not traced on iOS 16+.
Changes
Two
NSURLSessionTaskDelegatecallbacks are now instrumented for both ObjC and async/awaitcreated tasks:
URLSession:didCreateTask:(iOS 16+): entry point to attach aFPRNetworkTraceto thetask. Skips if the ObjC task creation swizzle already attached one.
URLSession:task:didFinishCollectingMetrics:(iOS 10+): exit point to complete andremove the trace. Uses
NSURLSessionTaskTransactionMetricsfor accurate byte counts. ThetraceCompletedguard inFPRNetworkTracemakes this safe to call more than once: forcompletion handler tasks the trace is already gone (early return); for delegate based tasks
this fires first and
didCompleteWithError:becomes a no op.Both hooks are wired into
FPRNSURLSessionDelegate(no user delegate) andFPRNSURLSessionDelegateInstrument(user delegate present, via class level swizzle andCopySelector).Testing
All existing tests pass.
New tests (
FPRNSURLSessionInstrumentTest)testDelegateURLSessionTaskDidFinishCollectingMetrics: real HTTP request against thehermetic test server, verifies the delegate flag is set and the trace removed after response.
testDelegateURLSessionTaskDidFinishCollectingMetricsCopiedForNonImplementingDelegate:verifies
CopySelectorinstallsdidFinishCollectingMetrics:on delegates that do notimplement it, ensuring async/await tasks are traced even for sparse delegate implementations.
testDidCreateTaskDoesNotDoubleTraceObjCCreatedTask: verifies that whendidCreateTask:fires for an ObjC created task the existing trace is preserved and no duplicate is created.
testDelegateURLSessionDidCreateTaskCalledOnIOS16: verifies thedidCreateTask:hookis wired through the class level swizzle and reaches the user delegate on iOS 16+.
Pre-existing test fixes
testDelegateURLSessionTaskDidCompleteWithError(FPRNSURLSessionInstrumentTest):replaced
http://nonurl+ 5 second DNS spin with stopped local server for a deterministic"connection refused" failure.
testConnectionDidFailWithError(FPRNSURLConnectionInstrumentTest): same fix. Thenew
didFinishCollectingMetrics:instrumentation added enough overhead to the shareddelegate queue to push the DNS timeout past the 2 second window.
API Changes