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-2334 Use DatadogContext in V1 scopes #981

Merged
merged 9 commits into from
Sep 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 6 additions & 18 deletions Datadog/Datadog.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

20 changes: 16 additions & 4 deletions Sources/Datadog/Core/FeaturesConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,21 @@ internal struct FeaturesConfiguration {
let proxyConfiguration: [AnyHashable: Any]?
let encryption: DataEncryption?
let serverDateProvider: ServerDateProvider?
let dateProvider: DateProvider
}

struct Logging {
let uploadURL: URL
let logEventMapper: LogEventMapper?
let dateProvider: DateProvider
let applicationBundleIdentifier: String
}

struct Tracing {
let uploadURL: URL
let uuidGenerator: TracingUUIDGenerator
let spanEventMapper: SpanEventMapper?
let dateProvider: DateProvider
}

struct RUM {
Expand All @@ -64,6 +68,7 @@ internal struct FeaturesConfiguration {
let onSessionStart: RUMSessionListener?
let firstPartyHosts: Set<String>
let vitalsFrequency: TimeInterval?
let dateProvider: DateProvider
}

struct URLSessionAutoInstrumentation {
Expand Down Expand Up @@ -152,6 +157,8 @@ extension FeaturesConfiguration {
Datadog.verbosityLevel = .debug
}

let dateProvider = SystemDateProvider()

let common = Common(
site: configuration.datadogEndpoint,
clientToken: try ifValid(clientToken: configuration.clientToken),
Expand All @@ -170,21 +177,25 @@ extension FeaturesConfiguration {
sdkVersion: sdkVersion,
proxyConfiguration: configuration.proxyConfiguration,
encryption: configuration.encryption,
serverDateProvider: configuration.serverDateProvider
serverDateProvider: configuration.serverDateProvider,
dateProvider: dateProvider
)

if configuration.loggingEnabled {
logging = Logging(
uploadURL: try ifValid(endpointURLString: logsEndpoint.url),
logEventMapper: configuration.logEventMapper
logEventMapper: configuration.logEventMapper,
dateProvider: dateProvider,
applicationBundleIdentifier: common.applicationBundleIdentifier
)
}

if configuration.tracingEnabled {
tracing = Tracing(
uploadURL: try ifValid(endpointURLString: tracesEndpoint.url),
uuidGenerator: DefaultTracingUUIDGenerator(),
spanEventMapper: configuration.spanEventMapper
spanEventMapper: configuration.spanEventMapper,
dateProvider: dateProvider
)
}

Expand Down Expand Up @@ -219,7 +230,8 @@ extension FeaturesConfiguration {
backgroundEventTrackingEnabled: configuration.rumBackgroundEventTrackingEnabled,
onSessionStart: configuration.rumSessionsListener,
firstPartyHosts: sanitizedHosts,
vitalsFrequency: configuration.mobileVitalsFrequency.timeInterval
vitalsFrequency: configuration.mobileVitalsFrequency.timeInterval,
dateProvider: dateProvider
)
} else {
let error = ProgrammerError(
Expand Down
44 changes: 0 additions & 44 deletions Sources/Datadog/Core/System/LaunchTimeProvider.swift

This file was deleted.

18 changes: 6 additions & 12 deletions Sources/Datadog/Datadog.swift
Original file line number Diff line number Diff line change
Expand Up @@ -175,18 +175,16 @@ public class Datadog {

let consentProvider = ConsentProvider(initialConsent: initialTrackingConsent)
let userInfoProvider = UserInfoProvider()
let dateProvider = SystemDateProvider()
let serverDateProvider = configuration.common.serverDateProvider ?? DatadogNTPDateProvider()
let dateCorrector = ServerDateCorrector(serverDateProvider: serverDateProvider)
let networkConnectionInfoProvider = NetworkConnectionInfoProvider()
let carrierInfoProvider = CarrierInfoProvider()
let launchTimeProvider = LaunchTimeProvider()
let appStateListener = AppStateListener(dateProvider: dateProvider)
let appStateListener = AppStateListener(dateProvider: configuration.common.dateProvider)

// Set default `DatadogCore`:
let core = DatadogCore(
directory: try CoreDirectory(in: Directory.cache(), from: configuration.common),
dateProvider: dateProvider,
dateProvider: configuration.common.dateProvider,
consentProvider: consentProvider,
userInfoProvider: userInfoProvider,
performance: configuration.common.performance,
Expand All @@ -195,18 +193,14 @@ public class Datadog {
v1Context: DatadogV1Context(
configuration: configuration.common,
device: .init(),
dateProvider: dateProvider,
dateCorrector: dateCorrector,
networkConnectionInfoProvider: networkConnectionInfoProvider,
carrierInfoProvider: carrierInfoProvider,
userInfoProvider: userInfoProvider,
appStateListener: appStateListener,
launchTimeProvider: launchTimeProvider
userInfoProvider: userInfoProvider
),
contextProvider: DatadogContextProvider(
configuration: configuration.common,
device: .init(),
dateProvider: dateProvider,
serverDateProvider: serverDateProvider
)
)
Expand All @@ -226,7 +220,7 @@ public class Datadog {
sdkVersion: configuration.common.sdkVersion,
applicationID: rumConfiguration.applicationID,
source: configuration.common.source,
dateProvider: dateProvider,
dateProvider: rumConfiguration.dateProvider,
dateCorrector: dateCorrector,
sampler: rumConfiguration.telemetrySampler
)
Expand All @@ -241,7 +235,7 @@ public class Datadog {
if let instrumentationConfiguration = rumConfiguration.instrumentation {
rumInstrumentation = RUMInstrumentation(
configuration: instrumentationConfiguration,
dateProvider: dateProvider
dateProvider: rumConfiguration.dateProvider
)

core.register(feature: rumInstrumentation)
Expand Down Expand Up @@ -285,7 +279,7 @@ public class Datadog {
if let urlSessionAutoInstrumentationConfiguration = configuration.urlSessionAutoInstrumentation {
urlSessionAutoInstrumentation = URLSessionAutoInstrumentation(
configuration: urlSessionAutoInstrumentationConfiguration,
dateProvider: dateProvider,
dateProvider: configuration.common.dateProvider,
appStateListener: appStateListener
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ internal final class DatadogContextProvider {
/// to make writes exclusive.
private let queue = DispatchQueue(
label: "com.datadoghq.core-context",
attributes: .concurrent
qos: .utility
Copy link
Member

Choose a reason for hiding this comment

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

Given it is serial now, it no longer makes sense to do .barrier in following code, no?

func write(block: @escaping (inout DatadogContext) -> Void) {
   queue.async(flags: .barrier)
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Indeed, .barrier will have no effect on the serial queue, but I would like to keep it for now and move back to concurrency with a better threading design later.

Copy link
Member

Choose a reason for hiding this comment

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

Got it 👌. Good to go as it is targeting feature branch 👍

)

private var subscriptions: [ContextValueSubscription]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ internal struct NWPathMonitorPublisher: ContextValuePublisher {
target: .global(qos: .utility)
)

let initialValue: NetworkConnectionInfo
let initialValue: NetworkConnectionInfo? = nil

private let monitor: NWPathMonitor
private let queue: DispatchQueue
Expand All @@ -37,17 +37,9 @@ internal struct NWPathMonitorPublisher: ContextValuePublisher {
) {
self.monitor = monitor
self.queue = queue
self.initialValue = .init(
reachability: .maybe,
availableInterfaces: nil,
supportsIPv4: nil,
supportsIPv6: nil,
isExpensive: nil,
isConstrained: nil
)
}

func publish(to receiver: @escaping ContextValueReceiver<NetworkConnectionInfo>) {
func publish(to receiver: @escaping ContextValueReceiver<NetworkConnectionInfo?>) {
monitor.pathUpdateHandler = {
let info = NetworkConnectionInfo($0)
receiver(info)
Expand Down Expand Up @@ -125,7 +117,7 @@ internal struct SCNetworkReachabilityReader: ContextValueReader {
self.init(reachability: reachability)
}

func read(to receiver: inout NetworkConnectionInfo) {
func read(to receiver: inout NetworkConnectionInfo?) {
receiver = NetworkConnectionInfo(reachability)
}
}
Expand Down
44 changes: 15 additions & 29 deletions Sources/Datadog/DatadogCore/DatadogCore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,12 @@ extension DatadogCore: DatadogV1CoreProtocol {
}

return DatadogCoreFeatureScope(
context: v1Context,
contextProvider: contextProvider,
storage: feature.storage
)
}

var context: DatadogV1Context? {
var legacyContext: DatadogV1Context? {
return v1Context
}

Expand Down Expand Up @@ -251,14 +251,16 @@ internal protocol V1Feature {
/// The execution block is currently running in `sync`, this will change once the
/// context is provided on it's own queue.
internal struct DatadogCoreFeatureScope: FeatureV1Scope {
let context: DatadogV1Context
let contextProvider: DatadogContextProvider
let storage: FeatureStorage

func eventWriteContext(_ block: (DatadogV1Context, Writer) throws -> Void) {
do {
try block(context, storage.writer)
} catch {
DD.telemetry.error("Failed to execute feature scope", error: error)
func eventWriteContext(_ block: @escaping (DatadogContext, Writer) throws -> Void) {
contextProvider.read { context in
do {
try block(context, storage.writer)
} catch {
DD.telemetry.error("Failed to execute feature scope", error: error)
}
}
}
}
Expand All @@ -269,44 +271,29 @@ extension DatadogV1Context {
/// - Parameters:
/// - configuration: The configuration.
/// - device: The device description.
/// - dateProvider: The local date provider.
/// - dateCorrector: The server date corrector.
/// - networkConnectionInfoProvider: The network info provider.
/// - carrierInfoProvider: The carrier info provider.
/// - userInfoProvider: The user info provider.
/// - appStateListener: The application state listener.
/// - launchTimeProvider: The launch time provider.
init(
configuration: CoreConfiguration,
device: DeviceInfo,
dateProvider: DateProvider,
dateCorrector: DateCorrector,
networkConnectionInfoProvider: NetworkConnectionInfoProviderType,
carrierInfoProvider: CarrierInfoProviderType,
userInfoProvider: UserInfoProvider,
appStateListener: AppStateListening,
launchTimeProvider: LaunchTimeProviderType
userInfoProvider: UserInfoProvider
) {
self.site = configuration.site
self.clientToken = configuration.clientToken
self.service = configuration.serviceName
self.env = configuration.environment
self.version = configuration.applicationVersion
self.source = configuration.source
self.sdkVersion = configuration.sdkVersion
self.ciAppOrigin = configuration.origin
self.applicationName = configuration.applicationName
self.applicationBundleIdentifier = configuration.applicationBundleIdentifier

self.sdkInitDate = dateProvider.now
self.device = device
self.dateProvider = dateProvider
self.dateCorrector = dateCorrector
self.networkConnectionInfoProvider = networkConnectionInfoProvider
self.carrierInfoProvider = carrierInfoProvider
self.userInfoProvider = userInfoProvider
self.appStateListener = appStateListener
self.launchTimeProvider = launchTimeProvider
}
}

Expand All @@ -320,7 +307,6 @@ extension DatadogContextProvider {
convenience init(
configuration: CoreConfiguration,
device: DeviceInfo,
dateProvider: DateProvider,
serverDateProvider: ServerDateProvider
) {
let context = DatadogContext(
Expand All @@ -334,12 +320,12 @@ extension DatadogContextProvider {
ciAppOrigin: configuration.origin,
applicationName: configuration.applicationName,
applicationBundleIdentifier: configuration.applicationBundleIdentifier,
sdkInitDate: dateProvider.now,
sdkInitDate: configuration.dateProvider.now,
device: device,
// this is a placeholder waiting for the `ApplicationStatePublisher`
// to be initialized on the main thread, this value will be overrided
// as soon as the subscription is made.
applicationStateHistory: .active(since: dateProvider.now)
applicationStateHistory: .active(since: configuration.dateProvider.now)
)

self.init(context: context)
Expand All @@ -353,7 +339,7 @@ extension DatadogContextProvider {
assign(reader: SCNetworkReachabilityReader(), to: \.networkConnectionInfo)
}

#if os(iOS)
#if os(iOS) && !targetEnvironment(macCatalyst)
if #available(iOS 12, *) {
subscribe(\.carrierInfo, to: iOS12CarrierInfoPublisher())
} else {
Expand All @@ -368,7 +354,7 @@ extension DatadogContextProvider {
#if os(iOS) || os(tvOS)
DispatchQueue.main.async {
// must be call on the main thread to read `UIApplication.State`
let applicationStatePublisher = ApplicationStatePublisher(dateProvider: dateProvider)
let applicationStatePublisher = ApplicationStatePublisher(dateProvider: configuration.dateProvider)
self.subscribe(\.applicationStateHistory, to: applicationStatePublisher)
}
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ internal struct DataUploadConditions {
}

func blockersForUpload(with context: DatadogContext) -> [Blocker] {
let reachability = context.networkConnectionInfo.reachability
guard let reachability = context.networkConnectionInfo?.reachability else {
// when `NetworkConnectionInfo` is not yet available
return [.networkReachability(description: "unknown")]
}
let networkIsReachable = reachability == .yes || reachability == .maybe
var blockers: [Blocker] = networkIsReachable ? [] : [.networkReachability(description: reachability.rawValue)]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ internal struct DatadogContext {
/// Represents the current state of the device network connectivity and interface.
/// The value can be `unknown` if the network interface is not available or if it has not
/// yet been evaluated.
var networkConnectionInfo: NetworkConnectionInfo = .unknown
var networkConnectionInfo: NetworkConnectionInfo?
Copy link
Member Author

Choose a reason for hiding this comment

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

Making this optional to keep previous behavior.


/// Carrier information.
///
Expand Down
Loading