mirror of
https://codeberg.org/timelimit/timelimit-android.git
synced 2025-10-06 11:59:57 +02:00
Handle race condition during sync
This commit is contained in:
parent
70f9a3df24
commit
da572df89a
3 changed files with 46 additions and 5 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* TimeLimit Copyright <C> 2019 Jonas Lochmann
|
||||
* TimeLimit Copyright <C> 2019 - 2021 Jonas Lochmann
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -51,6 +51,9 @@ interface PendingSyncActionDao {
|
|||
@Query("SELECT COUNT(*) FROM pending_sync_action")
|
||||
fun countAllActionsLive(): LiveData<Long>
|
||||
|
||||
@Query("SELECT COUNT(*) FROM pending_sync_action")
|
||||
fun countAllActions(): Long
|
||||
|
||||
@Query("SELECT * FROM pending_sync_action WHERE scheduled_for_upload = 0 ORDER BY sequence_number DESC")
|
||||
fun getLatestUnscheduledActionSync(): PendingSyncAction?
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* TimeLimit Copyright <C> 2019 - 2020 Jonas Lochmann
|
||||
* TimeLimit Copyright <C> 2019 - 2021 Jonas Lochmann
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -36,6 +36,15 @@ object ApplyServerDataStatus {
|
|||
|
||||
fun applyServerDataStatusSync(status: ServerDataStatus, database: Database, platformIntegration: PlatformIntegration) {
|
||||
database.runInTransaction {
|
||||
// this would override some local data which was not sent yet
|
||||
// so it's better to cancel in this case (or, more complicated,
|
||||
// apply the delta which was not sent locally)
|
||||
//
|
||||
// locking the database during a sync is no option as the network
|
||||
// connection could be really bad
|
||||
if (database.pendingSyncAction().countAllActions() > 0)
|
||||
throw PendingSyncActionException()
|
||||
|
||||
run {
|
||||
// apply ful version until and message
|
||||
|
||||
|
@ -539,4 +548,6 @@ object ApplyServerDataStatus {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PendingSyncActionException: RuntimeException()
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* TimeLimit Copyright <C> 2019 - 2020 Jonas Lochmann
|
||||
* TimeLimit Copyright <C> 2019 - 2021 Jonas Lochmann
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -33,6 +33,7 @@ import io.timelimit.android.sync.network.api.UnauthorizedHttpError
|
|||
import io.timelimit.android.ui.IsAppInForeground
|
||||
import io.timelimit.android.work.SyncInBackgroundWorker
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.withContext
|
||||
|
@ -190,8 +191,7 @@ class SyncUtil (private val logic: AppLogic) {
|
|||
}
|
||||
|
||||
try {
|
||||
pushActions(server = server)
|
||||
pullStatus(server = server)
|
||||
doSyncRoundRetryOnNewActions(server)
|
||||
|
||||
logic.syncNotificationLogic.sync(forceUiSync = false)
|
||||
} catch (ex: UnauthorizedHttpError) {
|
||||
|
@ -214,6 +214,33 @@ class SyncUtil (private val logic: AppLogic) {
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun doSyncRoundRetryOnNewActions(server: ServerLogic.ServerConfig) {
|
||||
// retry two times
|
||||
for (i in 1..2) {
|
||||
try {
|
||||
doSyncRound(server = server)
|
||||
|
||||
return
|
||||
} catch (ex: ApplyServerDataStatus.PendingSyncActionException) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
Log.d(LOG_TAG, "got new actions while receiving the status => retry")
|
||||
}
|
||||
|
||||
delay(250)
|
||||
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// and do not catch at the last time
|
||||
doSyncRound(server = server)
|
||||
}
|
||||
|
||||
private suspend fun doSyncRound(server: ServerLogic.ServerConfig) {
|
||||
pushActions(server = server)
|
||||
pullStatus(server = server)
|
||||
}
|
||||
|
||||
private suspend fun pushActions(server: ServerLogic.ServerConfig) {
|
||||
upload.uploadActions(server)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue