Skip to content

Commit fda7c3e

Browse files
authored
Merge pull request #2068 from OneSignal/operationrepo-init-async
[Improvement] make part of operationrepo initialization async
2 parents a3575c9 + 9e364ad commit fda7c3e

File tree

4 files changed

+62
-27
lines changed

4 files changed

+62
-27
lines changed

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/common/modeling/ModelStore.kt

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -154,31 +154,35 @@ abstract class ModelStore<TModel>(
154154
}
155155

156156
protected fun load() {
157+
if (name == null || _prefs == null) {
158+
return
159+
}
160+
161+
val str = _prefs.getString(PreferenceStores.ONESIGNAL, PreferenceOneSignalKeys.MODEL_STORE_PREFIX + name, "[]")
162+
val jsonArray = JSONArray(str)
157163
synchronized(models) {
158-
if (name != null && _prefs != null) {
159-
val str = _prefs.getString(PreferenceStores.ONESIGNAL, PreferenceOneSignalKeys.MODEL_STORE_PREFIX + name, "[]")
160-
val jsonArray = JSONArray(str)
161-
for (index in 0 until jsonArray.length()) {
162-
val newModel = create(jsonArray.getJSONObject(index)) ?: continue
163-
models.add(newModel)
164-
// listen for changes to this model
165-
newModel.subscribe(this)
166-
}
164+
for (index in 0 until jsonArray.length()) {
165+
val newModel = create(jsonArray.getJSONObject(index)) ?: continue
166+
models.add(newModel)
167+
// listen for changes to this model
168+
newModel.subscribe(this)
167169
}
168170
}
169171
}
170172

171173
fun persist() {
172-
synchronized(models) {
173-
if (name != null && _prefs != null) {
174-
val jsonArray = JSONArray()
175-
for (model in models) {
176-
jsonArray.put(model.toJSON())
177-
}
174+
if (name == null || _prefs == null) {
175+
return
176+
}
178177

179-
_prefs.saveString(PreferenceStores.ONESIGNAL, PreferenceOneSignalKeys.MODEL_STORE_PREFIX + name, jsonArray.toString())
178+
val jsonArray = JSONArray()
179+
synchronized(models) {
180+
for (model in models) {
181+
jsonArray.put(model.toJSON())
180182
}
181183
}
184+
185+
_prefs.saveString(PreferenceStores.ONESIGNAL, PreferenceOneSignalKeys.MODEL_STORE_PREFIX + name, jsonArray.toString())
182186
}
183187

184188
override fun subscribe(handler: IModelStoreChangeHandler<TModel>) = changeSubscription.subscribe(handler)

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/impl/OperationModelStore.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import com.onesignal.user.internal.operations.impl.executors.UpdateUserOperation
2828
import org.json.JSONObject
2929

3030
internal class OperationModelStore(prefs: IPreferencesService) : ModelStore<Operation>("operations", prefs) {
31-
init {
31+
fun loadOperations() {
3232
load()
3333
}
3434

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/impl/OperationRepo.kt

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,6 @@ internal class OperationRepo(
7878
}
7979
}
8080
this.executorsMap = executorsMap
81-
82-
for (operation in _operationModelStore.list()) {
83-
internalEnqueue(OperationQueueItem(operation, bucket = enqueueIntoBucket), flush = false, addToStore = false)
84-
}
8581
}
8682

8783
override fun <T : Operation> containsInstanceOf(type: KClass<T>): Boolean {
@@ -92,7 +88,11 @@ internal class OperationRepo(
9288

9389
override fun start() {
9490
paused = false
95-
coroutineScope.launch { processQueueForever() }
91+
coroutineScope.launch {
92+
// load saved operations first then start processing the queue to ensure correct operation order
93+
loadSavedOperations()
94+
processQueueForever()
95+
}
9696
}
9797

9898
override fun enqueue(
@@ -122,13 +122,18 @@ internal class OperationRepo(
122122
queueItem: OperationQueueItem,
123123
flush: Boolean,
124124
addToStore: Boolean,
125+
index: Int? = null,
125126
) {
126127
synchronized(queue) {
127-
queue.add(queueItem)
128-
if (addToStore) {
129-
_operationModelStore.add(queueItem.operation)
128+
if (index != null) {
129+
queue.add(index, queueItem)
130+
} else {
131+
queue.add(queueItem)
130132
}
131133
}
134+
if (addToStore) {
135+
_operationModelStore.add(queueItem.operation)
136+
}
132137

133138
waiter.wake(LoopWaiterMessage(flush, 0))
134139
}
@@ -344,12 +349,20 @@ internal class OperationRepo(
344349
}
345350

346351
val startingKey =
347-
if (startingOp.operation.groupComparisonType == GroupComparisonType.CREATE) startingOp.operation.createComparisonKey else startingOp.operation.modifyComparisonKey
352+
if (startingOp.operation.groupComparisonType == GroupComparisonType.CREATE) {
353+
startingOp.operation.createComparisonKey
354+
} else {
355+
startingOp.operation.modifyComparisonKey
356+
}
348357

349358
if (queue.isNotEmpty()) {
350359
for (item in queue.toList()) {
351360
val itemKey =
352-
if (startingOp.operation.groupComparisonType == GroupComparisonType.CREATE) item.operation.createComparisonKey else item.operation.modifyComparisonKey
361+
if (startingOp.operation.groupComparisonType == GroupComparisonType.CREATE) {
362+
item.operation.createComparisonKey
363+
} else {
364+
item.operation.modifyComparisonKey
365+
}
353366

354367
if (itemKey == "" && startingKey == "") {
355368
throw Exception("Both comparison keys can not be blank!")
@@ -364,4 +377,21 @@ internal class OperationRepo(
364377

365378
return ops
366379
}
380+
381+
/**
382+
* Load saved operations from preference service and add them into the queue
383+
* NOTE: Sometimes the loading might take longer than expected due to I/O reads from disk
384+
* Any I/O implies executing time will vary greatly.
385+
*/
386+
private fun loadSavedOperations() {
387+
_operationModelStore.loadOperations()
388+
for (operation in _operationModelStore.list().withIndex()) {
389+
internalEnqueue(
390+
OperationQueueItem(operation.value, bucket = enqueueIntoBucket),
391+
flush = false,
392+
addToStore = false,
393+
operation.index,
394+
)
395+
}
396+
}
367397
}

OneSignalSDK/onesignal/core/src/test/java/com/onesignal/core/internal/operations/OperationRepoTests.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ private class Mocks {
3535
val operationModelStore: OperationModelStore =
3636
run {
3737
val mockOperationModelStore = mockk<OperationModelStore>()
38+
every { mockOperationModelStore.loadOperations() } just runs
3839
every { mockOperationModelStore.list() } returns listOf()
3940
every { mockOperationModelStore.add(any()) } just runs
4041
every { mockOperationModelStore.remove(any()) } just runs

0 commit comments

Comments
 (0)