Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -154,31 +154,35 @@ abstract class ModelStore<TModel>(
}

protected fun load() {
if (name == null || _prefs == null) {
return
}

val str = _prefs.getString(PreferenceStores.ONESIGNAL, PreferenceOneSignalKeys.MODEL_STORE_PREFIX + name, "[]")
val jsonArray = JSONArray(str)
synchronized(models) {
if (name != null && _prefs != null) {
val str = _prefs.getString(PreferenceStores.ONESIGNAL, PreferenceOneSignalKeys.MODEL_STORE_PREFIX + name, "[]")
val jsonArray = JSONArray(str)
for (index in 0 until jsonArray.length()) {
val newModel = create(jsonArray.getJSONObject(index)) ?: continue
models.add(newModel)
// listen for changes to this model
newModel.subscribe(this)
}
for (index in 0 until jsonArray.length()) {
val newModel = create(jsonArray.getJSONObject(index)) ?: continue
models.add(newModel)
// listen for changes to this model
newModel.subscribe(this)
}
}
}

fun persist() {
synchronized(models) {
if (name != null && _prefs != null) {
val jsonArray = JSONArray()
for (model in models) {
jsonArray.put(model.toJSON())
}
if (name == null || _prefs == null) {
return
}

_prefs.saveString(PreferenceStores.ONESIGNAL, PreferenceOneSignalKeys.MODEL_STORE_PREFIX + name, jsonArray.toString())
val jsonArray = JSONArray()
synchronized(models) {
for (model in models) {
jsonArray.put(model.toJSON())
}
}

_prefs.saveString(PreferenceStores.ONESIGNAL, PreferenceOneSignalKeys.MODEL_STORE_PREFIX + name, jsonArray.toString())
}

override fun subscribe(handler: IModelStoreChangeHandler<TModel>) = changeSubscription.subscribe(handler)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import com.onesignal.user.internal.operations.impl.executors.UpdateUserOperation
import org.json.JSONObject

internal class OperationModelStore(prefs: IPreferencesService) : ModelStore<Operation>("operations", prefs) {
init {
fun loadOperations() {
load()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,6 @@ internal class OperationRepo(
}
}
this.executorsMap = executorsMap

for (operation in _operationModelStore.list()) {
internalEnqueue(OperationQueueItem(operation, bucket = enqueueIntoBucket), flush = false, addToStore = false)
}
}

override fun <T : Operation> containsInstanceOf(type: KClass<T>): Boolean {
Expand All @@ -91,7 +87,11 @@ internal class OperationRepo(

override fun start() {
paused = false
coroutineScope.launch { processQueueForever() }
coroutineScope.launch {
// load saved operations first then start processing the queue to ensure correct operation order
loadSavedOperations()
processQueueForever()
}
}

override fun enqueue(
Expand Down Expand Up @@ -121,13 +121,18 @@ internal class OperationRepo(
queueItem: OperationQueueItem,
flush: Boolean,
addToStore: Boolean,
index: Int? = null,
) {
synchronized(queue) {
queue.add(queueItem)
if (addToStore) {
_operationModelStore.add(queueItem.operation)
if (index != null) {
queue.add(index, queueItem)
} else {
queue.add(queueItem)
}
}
if (addToStore) {
_operationModelStore.add(queueItem.operation)
}

waiter.wake(LoopWaiterMessage(flush, 0))
}
Expand Down Expand Up @@ -332,12 +337,20 @@ internal class OperationRepo(
}

val startingKey =
if (startingOp.operation.groupComparisonType == GroupComparisonType.CREATE) startingOp.operation.createComparisonKey else startingOp.operation.modifyComparisonKey
if (startingOp.operation.groupComparisonType == GroupComparisonType.CREATE) {
startingOp.operation.createComparisonKey
} else {
startingOp.operation.modifyComparisonKey
}

if (queue.isNotEmpty()) {
for (item in queue.toList()) {
val itemKey =
if (startingOp.operation.groupComparisonType == GroupComparisonType.CREATE) item.operation.createComparisonKey else item.operation.modifyComparisonKey
if (startingOp.operation.groupComparisonType == GroupComparisonType.CREATE) {
item.operation.createComparisonKey
} else {
item.operation.modifyComparisonKey
}

if (itemKey == "" && startingKey == "") {
throw Exception("Both comparison keys can not be blank!")
Expand All @@ -352,4 +365,21 @@ internal class OperationRepo(

return ops
}

/**
* Load saved operations from preference service and add them into the queue
* NOTE: Sometimes the loading might take longer than expected due to I/O reads from disk
* Any I/O implies executing time will vary greatly.
*/
private fun loadSavedOperations() {
_operationModelStore.loadOperations()
for (operation in _operationModelStore.list().withIndex()) {
internalEnqueue(
OperationQueueItem(operation.value, bucket = enqueueIntoBucket),
flush = false,
addToStore = false,
operation.index,
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ private class Mocks {
val operationModelStore: OperationModelStore =
run {
val mockOperationModelStore = mockk<OperationModelStore>()
every { mockOperationModelStore.loadOperations() } just runs
every { mockOperationModelStore.list() } returns listOf()
every { mockOperationModelStore.add(any()) } just runs
every { mockOperationModelStore.remove(any()) } just runs
Expand Down