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

RUMM-2171 Use core feature scope in RUM #902

Merged
merged 5 commits into from
Jun 27, 2022

Conversation

maxep
Copy link
Member

@maxep maxep commented Jun 20, 2022

What and why?

RUMMonitor and scope instances now build and record events using V1FeatureScope provided by DatadogV1CoreProtocol.

How?

The RUMMonitor now keeps a reference to the provided core to retrieve the scope when a RUMCommand needs to be processed by RUMScopes. The RUMScope now expect a DatadogV1Context and a Writer to record events and apply side-effects.

Review checklist

  • Feature or bugfix MUST have appropriate tests (unit, integration)
  • Make sure each commit and the PR mention the Issue number or JIRA reference
  • Add CHANGELOG entry for user facing changes

Custom CI job configuration (optional)

  • Run unit tests
  • Run integration tests
  • Run smoke tests

@maxep maxep self-assigned this Jun 20, 2022
@maxep maxep force-pushed the maxep/RUMM-2171/rum-feature-scope branch from bd85422 to 482f482 Compare June 20, 2022 13:43
@maxep maxep force-pushed the maxep/RUMM-2171/rum-feature-scope branch from 174192d to d5cbeaf Compare June 22, 2022 17:08
@maxep maxep force-pushed the maxep/RUMM-2171/rum-feature-scope branch from d5cbeaf to 27cce00 Compare June 22, 2022 17:39
return childScope
}
/// Returns `self` to be kept open, `nil` if it requests to close.
func scope(byPropagating command: RUMCommand, context: DatadogV1Context, writer: Writer) -> Self? {
Copy link
Member Author

Choose a reason for hiding this comment

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

I've simplified the propagation methods signatures to better reflect its behaviour.

@maxep maxep marked this pull request as ready for review June 23, 2022 08:27
@maxep maxep requested a review from a team as a code owner June 23, 2022 08:27
@maxep maxep requested a review from ncreated June 23, 2022 09:47
Copy link
Member

@ncreated ncreated left a comment

Choose a reason for hiding this comment

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

I can see a huge effort here and it looks awesome 💪🏅.

All is good for me in this PR and we can merge. I left some suggestions trying to anticipate the future - please read all holistically as some might make more sense together.

service: dependencies.serviceName,
service: context.service,
session: .init(
hasReplay: nil,
id: context.sessionID.toRUMDataFormat,
id: self.context.sessionID.toRUMDataFormat,
type: dependencies.ciTest != nil ? .ciTest : .user
Copy link
Member

Choose a reason for hiding this comment

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

nit: to help differentiating between contexts, we could name it self.rumContext and sdkContext.

On the other hand both are well decoupled and we have enough type safety on them to avoid mistakes 👍. I'm only worried that in the future, when RUM context will be a part of the SDKContext it could be misleading (or even error-prone) here. Any thoughts @maxep ?

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree, it's confusing. I will rename that 👍

Copy link
Member Author

@maxep maxep Jun 27, 2022

Choose a reason for hiding this comment

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

Actually self.context is defined by RUMContextProvider protocol. So changing the definition will have a large impact. RUMContext will be merge in Core Context anyway!

Comment on lines 25 to 35
let appStateListener: AppStateListening
let deviceInfo: RUMDevice
let osInfo: RUMOperatingSystem
let userInfoProvider: RUMUserInfoProvider
let launchTimeProvider: LaunchTimeProviderType
let connectivityInfoProvider: RUMConnectivityInfoProvider
let serviceName: String
let applicationVersion: String
let sdkVersion: String
let source: String
let firstPartyURLsFilter: FirstPartyURLsFilter
let eventBuilder: RUMEventBuilder
let eventOutput: RUMEventOutput
let rumUUIDGenerator: RUMUUIDGenerator
/// Adjusts RUM events time (device time) to server time.
let dateCorrector: DateCorrectorType
/// Integration with Crash Reporting. It updates the crash context with RUM info.
/// `nil` if Crash Reporting feature is not enabled.
let crashContextIntegration: RUMWithCrashContextIntegration?
Copy link
Member

Choose a reason for hiding this comment

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

Nice to see it shrink 💪. I think that ultimately we should only keep RUM-specific properties in there and everything else should be passed through SDKContext, WDYT @maxep? Some of it is even possible now - e.g. I can see sdkInitDate and MobileDevice (transitive input for RUMDevice and RUMOperatingSystem) already defined in DatadogV1Context. If we agree, I think it's best to tackle them in separate PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah indeed, that's a good point! Also makes me realise that I forgot to remove the eventBuilder and eventOutput.
I've created a dedicated story for managing the context in a single queue, RUMM-2299, I can add that in the requirements!

Comment on lines -478 to +470
connectivity: dependencies.connectivityInfoProvider.current,
connectivity: .init(context: context),
Copy link
Member

Choose a reason for hiding this comment

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

Nice 👍. I think we should do the same for initializing other RUM data types from context, e.g.: RUMOperatingSystem, RUMDevice. Can be a separate PR IMO.

@@ -593,9 +596,16 @@ public class RUMMonitor: DDRUMMonitor, RUMCommandSubscriber {
// MARK: - RUMCommandSubscriber

func process(command: RUMCommand) {
guard let scope = core.v1.scope(for: RUMFeature.self) else {
return
Copy link
Member

Choose a reason for hiding this comment

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

(just checking) This return is unreachable, right? We do early-return in RUMMonitor.initialize() when RUMFeature is not registered, so it's not possible to run here.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, we do an early return in RUMMonitor.initialize() with appropriate console prints 👍

Comment on lines +73 to +77
_ = scope.process(
command: RUMStartUserActionCommand.mockAny(),
context: context,
writer: writer
)
Copy link
Member

Choose a reason for hiding this comment

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

After seeing this all over, I wonder if it wouldn't make sense to anticipate future needs by introducing container type bundling context and writer in RUMScope APIs. For example:

scope.process(command:rumScopeContext:)

where initially we will have:

internal struct RUMScopeContext {
   let sdkContext: DatadogV1Context
   let writer: Writer
}

I will keep door open for bundling other aspects (if necessary) without huge refactoring pain. WDYT @maxep ?

Copy link
Member Author

Choose a reason for hiding this comment

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

I would prefer to keep those 2 as arguments for now! It would be best to use a container once we have a larger list of parameters. Command processing is well contained into RUM scopes, it won't be too difficult to refactor 👍

@maxep maxep merged commit 507fee4 into feature/v2 Jun 27, 2022
@maxep maxep deleted the maxep/RUMM-2171/rum-feature-scope branch June 27, 2022 11: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.

2 participants