-
Notifications
You must be signed in to change notification settings - Fork 134
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
RUMM-2507 Create an ApplicationLaunch view during session initialization #1160
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.
Thanks, just made one small suggestion and also noticed a missing link
|
||
The ApplicationLaunch view includes any logs, actions, and resources created before your first call to `startView`. Use the duration of this view to determine time to first view. This view has an action, `application_start`, with a duration equal to the amount of time from process start until the call to `applicationDidBecomeActive`. | ||
|
||
In cases where iOS decides to [prewarm your application][4], the ApplicationLaunch view instead starts when the RUM iOS SDK is initialized, and the `application_start` event does not have a duration. |
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.
In cases where iOS decides to [prewarm your application][4], the ApplicationLaunch view instead starts when the RUM iOS SDK is initialized, and the `application_start` event does not have a duration. | |
In cases where iOS [prewarms your application][4], the ApplicationLaunch view instead starts when the RUM iOS SDK is initialized, and the `application_start` event does not have a duration. |
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.
Looks like the link for [4]
has not beed added yet
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 catch, thanks!
2be7c77
to
8d69847
Compare
523f160
to
570a9cf
Compare
Datadog ReportBranch report: ✅ |
private func startApplicationLaunchView(on command: RUMCommand, context: DatadogContext) { | ||
internal func startApplicationLaunchView(context: DatadogContext, writer: Writer) { |
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/ So far the RUMScopes architecture was only allowing side-effects that happen in response to RUMCommand
processing. Everything was implicit and the only internal API on scopes was:
func process(command: RUMCommand, context: DatadogContext, writer: Writer) -> Bool
Here we seem to break this convention and add a precedence: the "start app launch view" routine becomes explicit and can be called from outside, causing session scope to call arbitrary API on view scope. This adds extra complexity to an already complicated RUM architecture - to fully test it now, we'd need to cover all extra usages, like calling startApplicationLaunchView()
in already running RUM session.
Could we consider adopting this change without introducing new internal APIs in scopes? At the surface, it looks doable, because RUMSessionScope
has isInitialSession
flag and RUMViewScope
has its isInitialView
attribute. It looks that passing necessary timings and != .background
state to scopes .init()
could be enough.
Alternatively, maybe introducing RUMStartApplicationLaunchView
command could make RUM code simpler? Such command could be sent once from RUMMonitor
(right after initialising scopes). It shouldn't require introducing much new pieces to RUM scopes as well. Also, because it will be RUMMonitor
who emits that command, this won't require such strong surgery in RUM scopes unit tests like we had to do in this PR - the new logic would be additive.
I wonder what you think @maxep @fuzzybinary ?
@@ -6,6 +6,7 @@ | |||
|
|||
import Foundation | |||
import XCTest | |||
import Datadog |
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 we can't let this import here. The comment below says:
Note: this file is individually referenced by integration tests target, so no dependency on other source files
and IIRC this won't build in UI tests (the UI tests runner doesn't link Datadog
).
It seems to be a leftover after some other changes, no? I don't see any Datadog
symbols used below.
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, it's leftover. I originally did @testable import Datadog
which definitely didn't build for integration tests, though this did.
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.
It looks okay and I really appreciate the extra care for unit tests and changes in RUMSessionMatcher
we do here 👌.
We need to fix at least CI build (in integration tests) to move forward.
On top of that, I left an architectural suggestion. I wonder what you think @fuzzybinary and if it sounds like something that could simplify our implementation.
It's a good point, let's talk this morning and see which approach we like better. I'm leaning toward RUMStartApplicationLaunchView command, as we can have the initial view be not the ApplicationLaunch view. |
This leaves the functionality of the `application_start` action intact, but has it always added to it's own ApplicationLaunch view, instead of onto the first view that appears.
Since the RUMEventMatchers are used in integration tests, @testable isn't available for the Datadog module.
b8a2a54
to
af362be
Compare
Instead of exposing the `startInitialSession` and `sendApplicaitonLaunchEvent` funcitons, we'll instead use a specific command to do both.
af362be
to
40e29cf
Compare
if !isInitialView || viewPath != RUMOffViewEventsHandlingRule.Constants.applicationLaunchViewURL { | ||
DD.telemetry.error( | ||
id: "application-start-error", | ||
message: "An RUMApplciationStartCommand got sent to something other than the ApplicaitonLaunch view.", |
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.
message: "An RUMApplciationStartCommand got sent to something other than the ApplicaitonLaunch view.", | |
message: "A RUMApplicationStartCommand got sent to something other than the ApplicationLaunch view.", |
Co-authored-by: Louis Zawadzki <louiszawadzki@users.noreply.github.com>
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.
Looks great! I've left a small suggestion.
DD.telemetry.error( | ||
id: "application-start-error", | ||
message: "An RUMApplicationStartCommand got sent to something other than the ApplicationLaunch view.", | ||
kind: nil, | ||
stack: nil | ||
) |
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.
/nit You can use other signature available
DD.telemetry.error( | |
id: "application-start-error", | |
message: "An RUMApplicationStartCommand got sent to something other than the ApplicationLaunch view.", | |
kind: nil, | |
stack: nil | |
) | |
DD.telemetry.error("An RUMApplicationStartCommand got sent to something other than the ApplicationLaunch view.") |
The id
is inferred using file:line:message
.
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.
Maybe we can add the command type as part of the message, I'm afraid something
is not super actionable :)
1e83b86
to
a75a83c
Compare
func process(command: RUMCommand, context: DatadogContext, writer: Writer) -> Bool { | ||
if sessionScope == nil { | ||
startInitialSession(context: context) | ||
startInitialSession(on: command, context: context, writer: writer) |
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.
It rather seems we're starting initial session (along with the ApplicationLaunch
view) on first command received by RUMApplicationScope
. It looks different than what we say in PR description (and what we want):
Now, initializing the Datadog SDK with RUM will create the ApplicationLaunch view by default, staring at the process launch time.
No? If that is true, it would make more sense to just send the new command right after application scope init, somewhere 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.
Ah, I think I get it - we always do it (start the AL view), it is just that we await for any other command to do it. Makes sense - if the app starts idle and nothing happens, no session will be started 👍.
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.
That was my thought yes. It also made things a little bit cleaner as I could just use the context / writer as part of the command I was already recieving.
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.
Looks great! Thanks for looking into this alternative approach @fuzzybinary 💪. I left last question to make sure we got the requirement right - other than this, good to go 🚀.
What and why?
In order to more accurately track application launch and loading times, we are changing the way the ApplicationLaunch view work.
Now, initializing the Datadog SDK with RUM will create the ApplicationLaunch view by default, staring at the process launch time. This view can then track any resources, timing, or other events (including user actions) until the first call to startView.
The application_start event will now always be on the ApplicationLaunch view, but it's timing remains unchanged.
In the event of an active prewarm, the staring time of the ApplicationLaunch view is changed to the time the SDK was initialized, and the loading time of the application_start event is ignored.
How?
One big change to the UnitTests here is that now requesting RUM events from the matchers will discard the ApplicationLaunch view, as most tests assume such a view doesn't exist by default.
Review checklist
Custom CI job configuration (optional)