Skip to content

Commit bb9a9a8

Browse files
committed
RUM-386: Process feature context on the context thread
1 parent d4c9984 commit bb9a9a8

File tree

42 files changed

+1492
-526
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1492
-526
lines changed

dd-sdk-android-core/api/apiSurface

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ interface com.datadog.android.api.feature.FeatureSdkCore : com.datadog.android.a
119119
val internalLogger: com.datadog.android.api.InternalLogger
120120
fun registerFeature(Feature)
121121
fun getFeature(String): FeatureScope?
122-
fun updateFeatureContext(String, (MutableMap<String, Any?>) -> Unit)
123-
fun getFeatureContext(String): Map<String, Any?>
122+
fun updateFeatureContext(String, Boolean = true, (MutableMap<String, Any?>) -> Unit)
123+
fun getFeatureContext(String, Boolean = true): Map<String, Any?>
124124
fun setEventReceiver(String, FeatureEventReceiver)
125125
fun setContextUpdateReceiver(String, FeatureContextUpdateReceiver)
126126
fun removeContextUpdateReceiver(String, FeatureContextUpdateReceiver)
@@ -311,6 +311,8 @@ fun Collection<ByteArray>.join(ByteArray, ByteArray = ByteArray(0), ByteArray =
311311
fun java.util.concurrent.Executor.executeSafe(String, com.datadog.android.api.InternalLogger, Runnable)
312312
fun java.util.concurrent.ScheduledExecutorService.scheduleSafe(String, Long, java.util.concurrent.TimeUnit, com.datadog.android.api.InternalLogger, Runnable): java.util.concurrent.ScheduledFuture<*>?
313313
fun java.util.concurrent.ExecutorService.submitSafe(String, com.datadog.android.api.InternalLogger, Runnable): java.util.concurrent.Future<*>?
314+
fun <T> java.util.concurrent.ExecutorService.submitSafe(String, com.datadog.android.api.InternalLogger, java.util.concurrent.Callable<T>): java.util.concurrent.Future<T>?
315+
fun <T> java.util.concurrent.Future<T>?.getSafe(String, com.datadog.android.api.InternalLogger): T?
314316
val NULL_MAP_VALUE: Object
315317
object com.datadog.android.core.internal.utils.JsonSerializer
316318
fun toJsonElement(Any?): com.google.gson.JsonElement

dd-sdk-android-core/api/dd-sdk-android-core.api

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,15 +358,20 @@ public abstract interface class com/datadog/android/api/feature/FeatureSdkCore :
358358
public abstract fun createScheduledExecutorService (Ljava/lang/String;)Ljava/util/concurrent/ScheduledExecutorService;
359359
public abstract fun createSingleThreadExecutorService (Ljava/lang/String;)Ljava/util/concurrent/ExecutorService;
360360
public abstract fun getFeature (Ljava/lang/String;)Lcom/datadog/android/api/feature/FeatureScope;
361-
public abstract fun getFeatureContext (Ljava/lang/String;)Ljava/util/Map;
361+
public abstract fun getFeatureContext (Ljava/lang/String;Z)Ljava/util/Map;
362362
public abstract fun getInternalLogger ()Lcom/datadog/android/api/InternalLogger;
363363
public abstract fun registerFeature (Lcom/datadog/android/api/feature/Feature;)V
364364
public abstract fun removeContextUpdateReceiver (Ljava/lang/String;Lcom/datadog/android/api/feature/FeatureContextUpdateReceiver;)V
365365
public abstract fun removeEventReceiver (Ljava/lang/String;)V
366366
public abstract fun setAnonymousId (Ljava/util/UUID;)V
367367
public abstract fun setContextUpdateReceiver (Ljava/lang/String;Lcom/datadog/android/api/feature/FeatureContextUpdateReceiver;)V
368368
public abstract fun setEventReceiver (Ljava/lang/String;Lcom/datadog/android/api/feature/FeatureEventReceiver;)V
369-
public abstract fun updateFeatureContext (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
369+
public abstract fun updateFeatureContext (Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)V
370+
}
371+
372+
public final class com/datadog/android/api/feature/FeatureSdkCore$DefaultImpls {
373+
public static synthetic fun getFeatureContext$default (Lcom/datadog/android/api/feature/FeatureSdkCore;Ljava/lang/String;ZILjava/lang/Object;)Ljava/util/Map;
374+
public static synthetic fun updateFeatureContext$default (Lcom/datadog/android/api/feature/FeatureSdkCore;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
370375
}
371376

372377
public abstract interface class com/datadog/android/api/feature/StorageBackedFeature : com/datadog/android/api/feature/Feature {
@@ -812,8 +817,10 @@ public final class com/datadog/android/core/internal/utils/ByteArrayExtKt {
812817

813818
public final class com/datadog/android/core/internal/utils/ConcurrencyExtKt {
814819
public static final fun executeSafe (Ljava/util/concurrent/Executor;Ljava/lang/String;Lcom/datadog/android/api/InternalLogger;Ljava/lang/Runnable;)V
820+
public static final fun getSafe (Ljava/util/concurrent/Future;Ljava/lang/String;Lcom/datadog/android/api/InternalLogger;)Ljava/lang/Object;
815821
public static final fun scheduleSafe (Ljava/util/concurrent/ScheduledExecutorService;Ljava/lang/String;JLjava/util/concurrent/TimeUnit;Lcom/datadog/android/api/InternalLogger;Ljava/lang/Runnable;)Ljava/util/concurrent/ScheduledFuture;
816822
public static final fun submitSafe (Ljava/util/concurrent/ExecutorService;Ljava/lang/String;Lcom/datadog/android/api/InternalLogger;Ljava/lang/Runnable;)Ljava/util/concurrent/Future;
823+
public static final fun submitSafe (Ljava/util/concurrent/ExecutorService;Ljava/lang/String;Lcom/datadog/android/api/InternalLogger;Ljava/util/concurrent/Callable;)Ljava/util/concurrent/Future;
817824
}
818825

819826
public final class com/datadog/android/core/internal/utils/JsonSerializer {

dd-sdk-android-core/src/main/kotlin/com/datadog/android/api/feature/FeatureSdkCore.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,30 @@ interface FeatureSdkCore : SdkCore {
4545
* provided [featureName], a new one will be created.
4646
*
4747
* @param featureName Feature name.
48+
* @param useContextThread Whenever update of the context should happen on the context processing thread or not. It
49+
* should be true for most of the cases related to the event processing. Be careful when setting it to false, valid
50+
* use-case can be like updating/reading feature context on the same (or already on the context) thread.
51+
* Defaults to true.
4852
* @param updateCallback Provides current feature context for the update. If there is no feature
4953
* with the given name registered, callback won't be called.
5054
*/
5155
fun updateFeatureContext(
5256
featureName: String,
57+
useContextThread: Boolean = true,
5358
updateCallback: (context: MutableMap<String, Any?>) -> Unit
5459
)
5560

5661
/**
5762
* Retrieves the context for the particular feature.
5863
*
5964
* @param featureName Feature name.
65+
* @param useContextThread Whenever context read should happen on the context processing thread or not. It
66+
* should be true for most of the cases related to the event processing. Be careful when setting it to false, valid
67+
* use-case can be like updating/reading feature context on the same (or already on the context) thread.
68+
* Defaults to true.
6069
* @return Context for the given feature or empty map if feature is not registered.
6170
*/
62-
fun getFeatureContext(featureName: String): Map<String, Any?>
71+
fun getFeatureContext(featureName: String, useContextThread: Boolean = true): Map<String, Any?>
6372

6473
/**
6574
* Sets event receiver for the given feature.

dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/ContextProvider.kt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,8 @@ package com.datadog.android.core.internal
99
import com.datadog.android.api.context.DatadogContext
1010

1111
internal interface ContextProvider {
12-
// TODO RUM-3784 getting context may be quite heavy, should it be something non-blocking here?
13-
1412
// TODO RUM-3784 lifecycle checks may be needed for the cases when context is requested
1513
// when datadog is not initialized yet/anymore (case of UploadWorker, other calls site
1614
// should be in sync with lifecycle)
17-
18-
// TODO RUM-3784 can be accessed from different threads
1915
val context: DatadogContext
20-
21-
fun setFeatureContext(feature: String, context: Map<String, Any?>)
22-
23-
fun getFeatureContext(feature: String): Map<String, Any?>
2416
}

dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/CoreFeature.kt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ import java.io.File
9696
import java.io.FileNotFoundException
9797
import java.lang.ref.WeakReference
9898
import java.util.Locale
99-
import java.util.concurrent.ConcurrentHashMap
10099
import java.util.concurrent.ExecutorService
101100
import java.util.concurrent.LinkedBlockingQueue
102101
import java.util.concurrent.ScheduledExecutorService
@@ -123,7 +122,6 @@ internal class CoreFeature(
123122
internal var timeProvider: TimeProvider = NoOpTimeProvider()
124123
internal var trackingConsentProvider: ConsentProvider = NoOpConsentProvider()
125124
internal var userInfoProvider: MutableUserInfoProvider = NoOpMutableUserInfoProvider()
126-
internal var contextProvider: ContextProvider = NoOpContextProvider()
127125

128126
internal lateinit var okHttpClient: OkHttpClient
129127
internal var kronosClock: KronosClock? = null
@@ -155,8 +153,6 @@ internal class CoreFeature(
155153
internal lateinit var storageDir: File
156154
internal lateinit var androidInfoProvider: AndroidInfoProvider
157155

158-
internal val featuresContext: MutableMap<String, Map<String, Any?>> = ConcurrentHashMap()
159-
160156
internal val appStartTimeNs: Long
161157
get() = appStartTimeProvider.appStartTimeNs
162158

@@ -232,7 +228,6 @@ internal class CoreFeature(
232228
prepareNdkCrashData(nativeSourceOverride)
233229
setupInfoProviders(appContext, consent)
234230
initialized.set(true)
235-
contextProvider = DatadogContextProvider(this)
236231
}
237232

238233
fun stop() {
@@ -262,12 +257,9 @@ internal class CoreFeature(
262257
)
263258
}
264259

265-
featuresContext.clear()
266-
267260
initialized.set(false)
268261
ndkCrashHandler = NoOpNdkCrashHandler()
269262
trackingConsentProvider = NoOpConsentProvider()
270-
contextProvider = NoOpContextProvider()
271263
}
272264
}
273265

dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/DatadogContextProvider.kt

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ import com.datadog.android.api.context.ProcessInfo
1212
import com.datadog.android.api.context.TimeInfo
1313
import java.util.concurrent.TimeUnit
1414

15-
internal class DatadogContextProvider(val coreFeature: CoreFeature) : ContextProvider {
15+
internal class DatadogContextProvider(
16+
private val coreFeature: CoreFeature,
17+
private val featureContextProvider: FeatureContextProvider
18+
) : ContextProvider {
1619
override val context: DatadogContext
1720
get() {
1821
// IMPORTANT All properties should be immutable and be frozen at the state
@@ -64,19 +67,13 @@ internal class DatadogContextProvider(val coreFeature: CoreFeature) : ContextPro
6467
// Values at the top 2 levels are frozen: feature-name key,
6568
// and feature-specific-name key.
6669
featuresContext = mutableMapOf<String, Map<String, Any?>>().apply {
67-
val source = coreFeature.featuresContext
68-
source.forEach { (key, value) ->
69-
this[key] = value.toMap()
70+
featureContextProvider.getFeaturesContexts().forEach {
71+
val value = it.second()
72+
if (value.isNotEmpty()) {
73+
this[it.first] = value.toMap()
74+
}
7075
}
7176
}
7277
)
7378
}
74-
75-
override fun setFeatureContext(feature: String, context: Map<String, Any?>) {
76-
coreFeature.featuresContext[feature] = context
77-
}
78-
79-
override fun getFeatureContext(feature: String): Map<String, Any?> {
80-
return coreFeature.featuresContext[feature] ?: emptyMap()
81-
}
8279
}

0 commit comments

Comments
 (0)