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

RUM-4098: Use the datastore for Session Replay resources #2041

Merged
merged 8 commits into from
Jun 27, 2024
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
15 changes: 9 additions & 6 deletions dd-sdk-android-core/api/apiSurface
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,18 @@ data class com.datadog.android.api.storage.RawBatchEvent
constructor(ByteArray, ByteArray = EMPTY_BYTE_ARRAY)
override fun equals(Any?): Boolean
override fun hashCode(): Int
interface com.datadog.android.api.storage.datastore.DataStoreCallback<T: Any>
fun onSuccess(com.datadog.android.core.persistence.datastore.DataStoreContent<T>?)
fun onFailure()
interface com.datadog.android.api.storage.datastore.DataStoreHandler
fun <T: Any> setValue(String, T, Int = 0, com.datadog.android.core.persistence.Serializer<T>)
fun <T: Any> value(String, Int? = null, DataStoreCallback<T>, com.datadog.android.core.internal.persistence.Deserializer<String, T>)
fun removeValue(String)
fun <T: Any> setValue(String, T, Int = 0, DataStoreWriteCallback? = null, com.datadog.android.core.persistence.Serializer<T>)
fun <T: Any> value(String, Int? = null, DataStoreReadCallback<T>, com.datadog.android.core.internal.persistence.Deserializer<String, T>)
fun removeValue(String, DataStoreWriteCallback? = null)
companion object
const val CURRENT_DATASTORE_VERSION: Int
interface com.datadog.android.api.storage.datastore.DataStoreReadCallback<T: Any>
fun onSuccess(com.datadog.android.core.persistence.datastore.DataStoreContent<T>?)
fun onFailure()
interface com.datadog.android.api.storage.datastore.DataStoreWriteCallback
fun onSuccess()
fun onFailure()
interface com.datadog.android.core.InternalSdkCore : com.datadog.android.api.feature.FeatureSdkCore
val networkInfo: com.datadog.android.api.context.NetworkInfo
val trackingConsent: com.datadog.android.privacy.TrackingConsent
Expand Down
26 changes: 16 additions & 10 deletions dd-sdk-android-core/api/dd-sdk-android-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -463,26 +463,32 @@ public final class com/datadog/android/api/storage/RawBatchEvent {
public fun toString ()Ljava/lang/String;
}

public abstract interface class com/datadog/android/api/storage/datastore/DataStoreCallback {
public abstract fun onFailure ()V
public abstract fun onSuccess (Lcom/datadog/android/core/persistence/datastore/DataStoreContent;)V
}

public abstract interface class com/datadog/android/api/storage/datastore/DataStoreHandler {
public static final field CURRENT_DATASTORE_VERSION I
public static final field Companion Lcom/datadog/android/api/storage/datastore/DataStoreHandler$Companion;
public abstract fun removeValue (Ljava/lang/String;)V
public abstract fun setValue (Ljava/lang/String;Ljava/lang/Object;ILcom/datadog/android/core/persistence/Serializer;)V
public abstract fun value (Ljava/lang/String;Ljava/lang/Integer;Lcom/datadog/android/api/storage/datastore/DataStoreCallback;Lcom/datadog/android/core/internal/persistence/Deserializer;)V
public abstract fun removeValue (Ljava/lang/String;Lcom/datadog/android/api/storage/datastore/DataStoreWriteCallback;)V
public abstract fun setValue (Ljava/lang/String;Ljava/lang/Object;ILcom/datadog/android/api/storage/datastore/DataStoreWriteCallback;Lcom/datadog/android/core/persistence/Serializer;)V
public abstract fun value (Ljava/lang/String;Ljava/lang/Integer;Lcom/datadog/android/api/storage/datastore/DataStoreReadCallback;Lcom/datadog/android/core/internal/persistence/Deserializer;)V
}

public final class com/datadog/android/api/storage/datastore/DataStoreHandler$Companion {
public static final field CURRENT_DATASTORE_VERSION I
}

public final class com/datadog/android/api/storage/datastore/DataStoreHandler$DefaultImpls {
public static synthetic fun setValue$default (Lcom/datadog/android/api/storage/datastore/DataStoreHandler;Ljava/lang/String;Ljava/lang/Object;ILcom/datadog/android/core/persistence/Serializer;ILjava/lang/Object;)V
public static synthetic fun value$default (Lcom/datadog/android/api/storage/datastore/DataStoreHandler;Ljava/lang/String;Ljava/lang/Integer;Lcom/datadog/android/api/storage/datastore/DataStoreCallback;Lcom/datadog/android/core/internal/persistence/Deserializer;ILjava/lang/Object;)V
public static synthetic fun removeValue$default (Lcom/datadog/android/api/storage/datastore/DataStoreHandler;Ljava/lang/String;Lcom/datadog/android/api/storage/datastore/DataStoreWriteCallback;ILjava/lang/Object;)V
public static synthetic fun setValue$default (Lcom/datadog/android/api/storage/datastore/DataStoreHandler;Ljava/lang/String;Ljava/lang/Object;ILcom/datadog/android/api/storage/datastore/DataStoreWriteCallback;Lcom/datadog/android/core/persistence/Serializer;ILjava/lang/Object;)V
public static synthetic fun value$default (Lcom/datadog/android/api/storage/datastore/DataStoreHandler;Ljava/lang/String;Ljava/lang/Integer;Lcom/datadog/android/api/storage/datastore/DataStoreReadCallback;Lcom/datadog/android/core/internal/persistence/Deserializer;ILjava/lang/Object;)V
}

public abstract interface class com/datadog/android/api/storage/datastore/DataStoreReadCallback {
public abstract fun onFailure ()V
public abstract fun onSuccess (Lcom/datadog/android/core/persistence/datastore/DataStoreContent;)V
}

public abstract interface class com/datadog/android/api/storage/datastore/DataStoreWriteCallback {
public abstract fun onFailure ()V
public abstract fun onSuccess ()V
}

public abstract interface class com/datadog/android/core/InternalSdkCore : com/datadog/android/api/feature/FeatureSdkCore {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ interface DataStoreHandler {
* @param data to write.
* @param version optional version for the entry.
* If not specified will give the entry version 0 - even if that would be a downgrade from the previous version.
* @param callback (optional) to indicate whether the operation succeeded or not.
* @param serializer to use to serialize the data.
*/
fun <T : Any> setValue(
key: String,
data: T,
version: Int = 0,
callback: DataStoreWriteCallback? = null,
serializer: Serializer<T>
)

Expand All @@ -46,7 +48,7 @@ interface DataStoreHandler {
fun <T : Any> value(
key: String,
version: Int? = null,
callback: DataStoreCallback<T>,
callback: DataStoreReadCallback<T>,
deserializer: Deserializer<String, T>
)

Expand All @@ -55,9 +57,11 @@ interface DataStoreHandler {
* This executes on a worker thread and not on the caller thread.
*
* @param key name of the datastore entry
* @param callback (optional) to indicate whether the operation succeeded or not.
*/
fun removeValue(
key: String
key: String,
callback: DataStoreWriteCallback? = null
)

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@ package com.datadog.android.api.storage.datastore
import com.datadog.android.core.persistence.datastore.DataStoreContent

/**
* Callback for asynchronous operations on the datastore.
* Callback for asynchronous read operations on the datastore.
* @param T the datatype being retrieved.
*/
interface DataStoreCallback<T : Any> {
interface DataStoreReadCallback<T : Any> {

/**
* Triggered on successfully fetching data from the datastore.
* Triggered on successfully reading data from the datastore.
*
* @param dataStoreContent (nullable) contains the datastore content if there was data to fetch, else null.
*/
fun onSuccess(dataStoreContent: DataStoreContent<T>?)

/**
* Triggered when we failed to get data from the datastore.
* Triggered on failing to read data from the datastore.
*/
fun onFailure()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
* This product includes software developed at Datadog (https://www.datadoghq.com/).
* Copyright 2016-Present Datadog, Inc.
*/

package com.datadog.android.api.storage.datastore

/**
* Callback for asynchronous write operations on the datastore.
*/
interface DataStoreWriteCallback {
/**
* Triggered on successfully writing data to the datastore.
*/
fun onSuccess()

/**
* Triggered on failing to write data to the datastore.
*/
fun onFailure()
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
package com.datadog.android.core.internal.persistence.datastore

import com.datadog.android.api.InternalLogger
import com.datadog.android.api.storage.datastore.DataStoreCallback
import com.datadog.android.api.storage.datastore.DataStoreHandler
import com.datadog.android.api.storage.datastore.DataStoreReadCallback
import com.datadog.android.api.storage.datastore.DataStoreWriteCallback
import com.datadog.android.core.internal.persistence.Deserializer
import com.datadog.android.core.internal.utils.executeSafe
import com.datadog.android.core.persistence.Serializer
Expand All @@ -25,23 +26,24 @@ internal class DataStoreFileHandler(
key: String,
data: T,
version: Int,
callback: DataStoreWriteCallback?,
serializer: Serializer<T>
) {
executorService.executeSafe("dataStoreWrite", internalLogger) {
datastoreFileWriter.write(key, data, serializer, version)
datastoreFileWriter.write(key, data, serializer, callback, version)
}
}

override fun removeValue(key: String) {
override fun removeValue(key: String, callback: DataStoreWriteCallback?) {
executorService.executeSafe("dataStoreRemove", internalLogger) {
datastoreFileWriter.delete(key)
datastoreFileWriter.delete(key, callback)
}
}

override fun <T : Any> value(
key: String,
version: Int?,
callback: DataStoreCallback<T>,
callback: DataStoreReadCallback<T>,
deserializer: Deserializer<String, T>
) {
executorService.executeSafe("dataStoreRead", internalLogger) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ package com.datadog.android.core.internal.persistence.datastore

import androidx.annotation.WorkerThread
import com.datadog.android.api.InternalLogger
import com.datadog.android.api.storage.datastore.DataStoreCallback
import com.datadog.android.api.storage.datastore.DataStoreReadCallback
import com.datadog.android.core.internal.persistence.Deserializer
import com.datadog.android.core.internal.persistence.datastore.ext.toInt
import com.datadog.android.core.internal.persistence.file.existsSafe
Expand All @@ -31,7 +31,7 @@ internal class DatastoreFileReader(
key: String,
deserializer: Deserializer<String, T>,
version: Int? = null,
callback: DataStoreCallback<T>
callback: DataStoreReadCallback<T>
) {
val datastoreFile = dataStoreFileHelper.getDataStoreFile(
featureName = featureName,
Expand All @@ -53,7 +53,7 @@ internal class DatastoreFileReader(
deserializer: Deserializer<String, T>,
tlvBlockFileReader: TLVBlockFileReader,
requestedVersion: Int?,
callback: DataStoreCallback<T>
callback: DataStoreReadCallback<T>
) {
val tlvBlocks = tlvBlockFileReader.read(datastoreFile)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package com.datadog.android.core.internal.persistence.datastore

import androidx.annotation.WorkerThread
import com.datadog.android.api.InternalLogger
import com.datadog.android.api.storage.datastore.DataStoreWriteCallback
import com.datadog.android.core.internal.persistence.datastore.ext.toByteArray
import com.datadog.android.core.internal.persistence.file.FileReaderWriter
import com.datadog.android.core.internal.persistence.file.deleteSafe
Expand All @@ -30,6 +31,7 @@ internal class DatastoreFileWriter(
key: String,
data: T,
serializer: Serializer<T>,
callback: DataStoreWriteCallback?,
version: Int
) {
val datastoreFile = dataStoreFileHelper.getDataStoreFile(
Expand All @@ -43,6 +45,7 @@ internal class DatastoreFileWriter(

// failed to serialize one or more blocks
if (versionCodeBlock == null || dataBlock == null) {
callback?.onFailure()
return
}

Expand All @@ -51,23 +54,34 @@ internal class DatastoreFileWriter(
internalLogger = internalLogger
)

fileReaderWriter.writeData(
val result = fileReaderWriter.writeData(
file = datastoreFile,
data = dataToWrite,
append = false
)

if (result) {
callback?.onSuccess()
} else {
callback?.onFailure()
}
}

@WorkerThread
internal fun delete(key: String) {
internal fun delete(key: String, callback: DataStoreWriteCallback?) {
val datastoreFile = dataStoreFileHelper.getDataStoreFile(
featureName = featureName,
storageDir = storageDir,
key = key
)

if (datastoreFile.existsSafe(internalLogger)) {
datastoreFile.deleteSafe(internalLogger)
val result = datastoreFile.deleteSafe(internalLogger)
if (result) {
callback?.onSuccess()
} else {
callback?.onFailure()
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

package com.datadog.android.core.internal.persistence.datastore

import com.datadog.android.api.storage.datastore.DataStoreCallback
import com.datadog.android.api.storage.datastore.DataStoreHandler
import com.datadog.android.api.storage.datastore.DataStoreReadCallback
import com.datadog.android.api.storage.datastore.DataStoreWriteCallback
import com.datadog.android.core.internal.persistence.Deserializer
import com.datadog.android.core.persistence.Serializer

Expand All @@ -16,6 +17,7 @@ internal class NoOpDataStoreHandler : DataStoreHandler {
key: String,
data: T,
version: Int,
callback: DataStoreWriteCallback?,
serializer: Serializer<T>
) {
// NoOp Implementation
Expand All @@ -24,13 +26,16 @@ internal class NoOpDataStoreHandler : DataStoreHandler {
override fun <T : Any> value(
key: String,
version: Int?,
callback: DataStoreCallback<T>,
callback: DataStoreReadCallback<T>,
deserializer: Deserializer<String, T>
) {
// NoOp Implementation
}

override fun removeValue(key: String) {
override fun removeValue(
key: String,
callback: DataStoreWriteCallback?
) {
// NoOp Implementation
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
package com.datadog.android.core.internal.persistence.file.datastore

import com.datadog.android.api.InternalLogger
import com.datadog.android.api.storage.datastore.DataStoreCallback
import com.datadog.android.api.storage.datastore.DataStoreReadCallback
import com.datadog.android.api.storage.datastore.DataStoreWriteCallback
import com.datadog.android.core.internal.persistence.Deserializer
import com.datadog.android.core.internal.persistence.datastore.DataStoreFileHandler
import com.datadog.android.core.internal.persistence.datastore.DatastoreFileReader
Expand Down Expand Up @@ -61,6 +62,9 @@ internal class DataStoreFileHandlerTest {
@Mock
lateinit var mockSerializer: Serializer<String>

@Mock
lateinit var mockDataStoreWriteCallback: DataStoreWriteCallback

@StringForgery
lateinit var fakeFeatureName: String

Expand All @@ -70,15 +74,15 @@ internal class DataStoreFileHandlerTest {
@StringForgery
lateinit var fakeDataString: String

private lateinit var fileCallback: DataStoreCallback<ByteArray>
private lateinit var fileCallback: DataStoreReadCallback<ByteArray>

@BeforeEach
fun setup() {
whenever(mockExecutorService.execute(any())) doAnswer {
it.getArgument<Runnable>(0).run()
}

fileCallback = object : DataStoreCallback<ByteArray> {
fileCallback = object : DataStoreReadCallback<ByteArray> {
override fun onSuccess(dataStoreContent: DataStoreContent<ByteArray>?) {}
override fun onFailure() {}
}
Expand Down Expand Up @@ -138,6 +142,7 @@ internal class DataStoreFileHandlerTest {
key = fakeKey,
data = fakeDataString,
version = fakeVersion,
callback = mockDataStoreWriteCallback,
serializer = mockSerializer
)

Expand All @@ -146,6 +151,7 @@ internal class DataStoreFileHandlerTest {
key = fakeKey,
data = fakeDataString,
serializer = mockSerializer,
callback = mockDataStoreWriteCallback,
version = fakeVersion
)
}
Expand All @@ -154,12 +160,14 @@ internal class DataStoreFileHandlerTest {
fun `M call dataStoreWriter W removeValue()`() {
// When
testedDataStoreHandler.removeValue(
key = fakeKey
key = fakeKey,
callback = mockDataStoreWriteCallback
)

// Then
verify(mockDatastoreFileWriter).delete(
key = fakeKey
key = fakeKey,
callback = mockDataStoreWriteCallback
)
}
}
Loading