feat: add remote sync capability - downloader will now wait when upload scheduler is throttling job

This commit is contained in:
Martin Filo 2023-05-08 19:45:34 +02:00
parent dee51d8695
commit 0405cdca7f
3 changed files with 23 additions and 7 deletions

View file

@ -105,10 +105,13 @@ interface BackupAPI<LOGIN_DATA> {
restore(newData, keysToUpdate)
}
var willQueueSoon: Boolean?
var uploadJob: Job?
fun shouldUpdate(changedKey: String, isSettings: Boolean): Boolean
fun addToQueue(changedKey: String, isSettings: Boolean) {
if (!shouldUpdate(changedKey, isSettings)) {
willQueueSoon = false
Log.d(LOG_KEY, "upload not required, data is same")
return
}
@ -122,6 +125,7 @@ interface BackupAPI<LOGIN_DATA> {
}
uploadJob = ioScope.launchSafe {
willQueueSoon = false
Log.d(LOG_KEY, "upload is running now")
uploadSyncData()
}

View file

@ -39,11 +39,9 @@ import java.util.Date
*
* | State | Priority | Description
* |---------:|:--------:|---------------------------------------------------------------------
* | Progress | 1 | When scheduler has queued upload job (but is not working in backupApi
* | | | yet) we should postpone download and prioritize upload
* | Waiting | 2 | Add button to manually trigger sync
* | Waiting | 3 | Move "https://chiff.github.io/cloudstream-sync/google-drive"
* | Waiting | 5 | Choose what should be synced and recheck `invalidKeys` in createBackupScheduler
* | Someday | 4 | Add button to manually trigger sync
* | Someday | 5 | Choose what should be synced and recheck `invalidKeys` in createBackupScheduler
* | Someday | 3 | Add option to use proper OAuth through Google Services One Tap
* | Someday | 5 | Encrypt data on Drive (low priority)
* | Solved | 1 | Racing conditions when multiple devices in use
@ -53,6 +51,8 @@ import java.util.Date
* | Solved | 4 | Implement backup before user quits application
* | Solved | 1 | Do not write sync meta when user is not syncing data
* | Solved | 1 | Fix sync/restore bugs
* | Solved | 1 | When scheduler has queued upload job (but is not working in backupApi
* | | | yet) we should postpone download and prioritize upload
*/
class GoogleDriveApi(index: Int) :
InAppOAuth2APIManager(index),
@ -74,6 +74,7 @@ class GoogleDriveApi(index: Int) :
override val defaultRedirectUrl = "https://chiff.github.io/cloudstream-sync/google-drive"
override var isActive: Boolean? = false
override var willQueueSoon: Boolean? = false
override var uploadJob: Job? = null
private var tempAuthFlow: AuthorizationCodeFlow? = null
@ -344,8 +345,8 @@ class GoogleDriveApi(index: Int) :
// Internal
private val continuousDownloader = Scheduler<Boolean>(
BackupAPI.DOWNLOAD_THROTTLE.inWholeMilliseconds,
{ overwrite ->
if (uploadJob?.isActive == true) {
onWork = { overwrite ->
if (uploadJob?.isActive == true || willQueueSoon == true) {
uploadJob!!.invokeOnCompletion {
Log.d(LOG_KEY, "upload is running, reschedule download")
runDownloader(false, overwrite == true)
@ -357,7 +358,8 @@ class GoogleDriveApi(index: Int) :
}
runDownloader()
}
})
}
)
private fun runDownloader(runNow: Boolean = false, overwrite: Boolean = false) {
if (runNow) {

View file

@ -15,6 +15,7 @@ import com.lagradost.cloudstream3.utils.BackupUtils.nonTransferableKeys
class Scheduler<INPUT>(
private val throttleTimeMs: Long,
private val onWork: (INPUT?) -> Unit,
private val beforeWork: ((INPUT?) -> Unit)? = null,
private val canWork: ((INPUT?) -> Boolean)? = null
) {
companion object {
@ -44,6 +45,13 @@ class Scheduler<INPUT>(
)
}
},
beforeWork = {
AccountManager.BackupApis.filter {
it.isActive == true
}.forEach {
it.willQueueSoon = true
}
},
canWork = { input ->
if (input == null) {
throw IllegalStateException()
@ -111,6 +119,7 @@ class Scheduler<INPUT>(
}
Log.d(BackupAPI.LOG_KEY, "[$id] wants to schedule [${input}]")
beforeWork?.invoke(input)
throttle(input)
return true
@ -124,6 +133,7 @@ class Scheduler<INPUT>(
Log.d(BackupAPI.LOG_KEY, "[$id] runs immediate [${input}]")
beforeWork?.invoke(input)
stop()
onWork(input)