Skip to content

Commit

Permalink
feat: switch storage for better thread safety (#181)
Browse files Browse the repository at this point in the history
  • Loading branch information
qingzhuozhen authored Mar 1, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 3bf4922 commit 918d2d5
Showing 18 changed files with 1,526 additions and 274 deletions.
9 changes: 5 additions & 4 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -6,14 +6,15 @@ jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up JDK 11
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'zulu'

- name: Checkout
uses: actions/checkout@v3
cache: 'gradle'

- name: Setup Docs
run: ./gradlew dokkaHtmlMultiModule
7 changes: 4 additions & 3 deletions .github/workflows/pull-request-test.yml
Original file line number Diff line number Diff line change
@@ -6,12 +6,13 @@ jobs:
test:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- name: Set up JDK 11
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'temurin'
- uses: actions/checkout@v3
cache: 'gradle'
- name: Build
run: ./gradlew build
- name: Unit Test
@@ -20,7 +21,7 @@ jobs:
run: ./gradlew ktlintCheck
- name: Upload build results
if: always()
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
# artifacts name
name: build-results
5 changes: 3 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -26,13 +26,14 @@ jobs:
needs: [authorize]
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Set up JDK 11
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'zulu'
cache: 'gradle'

- name: Build
run: ./gradlew build
Original file line number Diff line number Diff line change
@@ -5,21 +5,22 @@ import com.amplitude.android.Configuration
import com.amplitude.android.utilities.AndroidStorage

class ApiKeyStorageMigration(
private val amplitude: Amplitude
private val amplitude: Amplitude,
) {
suspend fun execute() {
val configuration = amplitude.configuration as Configuration
val logger = amplitude.logger

val storage = amplitude.storage as? AndroidStorage
if (storage != null) {
val apiKeyStorage = AndroidStorage(configuration.context, configuration.apiKey, logger, storage.prefix)
val apiKeyStorage = AndroidStorage(configuration.context, configuration.apiKey, logger, storage.prefix, amplitude.diagnostics)
StorageKeyMigration(apiKeyStorage, storage, logger).execute()
}

val identifyInterceptStorage = amplitude.identifyInterceptStorage as? AndroidStorage
if (identifyInterceptStorage != null) {
val apiKeyStorage = AndroidStorage(configuration.context, configuration.apiKey, logger, identifyInterceptStorage.prefix)
val apiKeyStorage =
AndroidStorage(configuration.context, configuration.apiKey, logger, identifyInterceptStorage.prefix, amplitude.diagnostics)
StorageKeyMigration(apiKeyStorage, identifyInterceptStorage, logger).execute()
}
}
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ import com.amplitude.core.Storage
import com.amplitude.core.StorageProvider
import com.amplitude.core.events.BaseEvent
import com.amplitude.core.platform.EventPipeline
import com.amplitude.core.utilities.Diagnostics
import com.amplitude.core.utilities.EventsFileManager
import com.amplitude.core.utilities.EventsFileStorage
import com.amplitude.core.utilities.FileResponseHandler
@@ -24,9 +25,9 @@ class AndroidStorage(
context: Context,
val storageKey: String,
private val logger: Logger,
internal val prefix: String?
internal val prefix: String?,
private val diagnostics: Diagnostics,
) : Storage, EventsFileStorage {

companion object {
const val STORAGE_PREFIX = "amplitude-android"
}
@@ -35,7 +36,7 @@ class AndroidStorage(
context.getSharedPreferences("${getPrefix()}-$storageKey", Context.MODE_PRIVATE)
private val storageDirectory: File = context.getDir(getDir(), Context.MODE_PRIVATE)
private val eventsFile =
EventsFileManager(storageDirectory, storageKey, AndroidKVS(sharedPreferences))
EventsFileManager(storageDirectory, storageKey, AndroidKVS(sharedPreferences), logger, diagnostics)
private val eventCallbacksMap = mutableMapOf<String, EventCallBack>()

override suspend fun writeEvent(event: BaseEvent) {
@@ -47,7 +48,10 @@ class AndroidStorage(
}
}

override suspend fun write(key: Storage.Constants, value: String) {
override suspend fun write(
key: Storage.Constants,
value: String,
) {
sharedPreferences.edit().putString(key.rawVal, value).apply()
}

@@ -87,7 +91,7 @@ class AndroidStorage(
configuration,
scope,
dispatcher,
logger
logger,
)
}

@@ -103,7 +107,10 @@ class AndroidStorage(
eventCallbacksMap.remove(insertId)
}

override fun splitEventFile(filePath: String, events: JSONArray) {
override fun splitEventFile(
filePath: String,
events: JSONArray,
) {
eventsFile.splitFile(filePath, events)
}

@@ -120,13 +127,17 @@ class AndroidStorage(
}

class AndroidStorageProvider : StorageProvider {
override fun getStorage(amplitude: Amplitude, prefix: String?): Storage {
override fun getStorage(
amplitude: Amplitude,
prefix: String?,
): Storage {
val configuration = amplitude.configuration as com.amplitude.android.Configuration
return AndroidStorage(
configuration.context,
configuration.instanceName,
configuration.loggerProvider.getLogger(amplitude),
prefix
prefix,
amplitude.diagnostics,
)
}
}
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ import com.amplitude.android.utilities.AndroidStorage
import com.amplitude.common.jvm.ConsoleLogger
import com.amplitude.core.Storage
import com.amplitude.core.events.BaseEvent
import com.amplitude.core.utilities.Diagnostics
import kotlinx.coroutines.runBlocking
import org.junit.Test
import org.junit.jupiter.api.Assertions
@@ -16,13 +17,15 @@ import java.util.UUID

@RunWith(RobolectricTestRunner::class)
class StorageKeyMigrationTest {
private val testDiagnostics = Diagnostics()

@Test
fun `simple values should be migrated`() {
val context = ApplicationProvider.getApplicationContext<Context>()
val logger = ConsoleLogger()

val source = AndroidStorage(context, UUID.randomUUID().toString(), logger, null)
val destination = AndroidStorage(context, UUID.randomUUID().toString(), logger, null)
val source = AndroidStorage(context, UUID.randomUUID().toString(), logger, null, testDiagnostics)
val destination = AndroidStorage(context, UUID.randomUUID().toString(), logger, null, testDiagnostics)
val sourceFileIndexKey = "amplitude.events.file.index.${source.storageKey}"
val destinationFileIndexKey = "amplitude.events.file.index.${destination.storageKey}"

@@ -74,8 +77,8 @@ class StorageKeyMigrationTest {
val context = ApplicationProvider.getApplicationContext<Context>()
val logger = ConsoleLogger()

val source = AndroidStorage(context, UUID.randomUUID().toString(), logger, null)
val destination = AndroidStorage(context, UUID.randomUUID().toString(), logger, null)
val source = AndroidStorage(context, UUID.randomUUID().toString(), logger, null, testDiagnostics)
val destination = AndroidStorage(context, UUID.randomUUID().toString(), logger, null, testDiagnostics)

runBlocking {
source.writeEvent(createEvent(1))
@@ -117,8 +120,8 @@ class StorageKeyMigrationTest {
val context = ApplicationProvider.getApplicationContext<Context>()
val logger = ConsoleLogger()

val source = AndroidStorage(context, UUID.randomUUID().toString(), logger, null)
val destination = AndroidStorage(context, UUID.randomUUID().toString(), logger, null)
val source = AndroidStorage(context, UUID.randomUUID().toString(), logger, null, testDiagnostics)
val destination = AndroidStorage(context, UUID.randomUUID().toString(), logger, null, testDiagnostics)

var destinationPreviousSessionId = destination.read(Storage.Constants.PREVIOUS_SESSION_ID)
var destinationLastEventTime = destination.read(Storage.Constants.LAST_EVENT_TIME)
@@ -150,8 +153,8 @@ class StorageKeyMigrationTest {
val context = ApplicationProvider.getApplicationContext<Context>()
val logger = ConsoleLogger()

val source = AndroidStorage(context, UUID.randomUUID().toString(), logger, null)
val destination = AndroidStorage(context, UUID.randomUUID().toString(), logger, null)
val source = AndroidStorage(context, UUID.randomUUID().toString(), logger, null, testDiagnostics)
val destination = AndroidStorage(context, UUID.randomUUID().toString(), logger, null, testDiagnostics)

runBlocking {
source.writeEvent(createEvent(1))
Loading

0 comments on commit 918d2d5

Please sign in to comment.