Skip to content

Commit

Permalink
Merge pull request #12372 from nextcloud/make_sync_service_run_only_once
Browse files Browse the repository at this point in the history
Make sync worker only run when needed
  • Loading branch information
alperozturk96 committed May 3, 2024
2 parents 956b675 + f23b0bd commit f027458
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,5 @@ interface BackgroundJobManager {
fun cancelAllJobs()
fun schedulePeriodicHealthStatus()
fun startHealthStatus()
fun bothFilesSyncJobsRunning(): Boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import com.nextcloud.client.documentscan.GeneratePdfFromImagesWork
import com.nextcloud.client.jobs.download.FileDownloadWorker
import com.nextcloud.client.jobs.upload.FileUploadWorker
import com.nextcloud.client.preferences.AppPreferences
import com.nextcloud.utils.extensions.isWorkRunning
import com.nextcloud.utils.extensions.isWorkScheduled
import com.owncloud.android.datamodel.OCFile
import com.owncloud.android.operations.DownloadType
Expand Down Expand Up @@ -403,6 +404,11 @@ internal class BackgroundJobManagerImpl(
workManager.cancelJob(JOB_PERIODIC_CALENDAR_BACKUP, user)
}

override fun bothFilesSyncJobsRunning(): Boolean {
return workManager.isWorkRunning(JOB_PERIODIC_FILES_SYNC) &&
workManager.isWorkRunning(JOB_IMMEDIATE_FILES_SYNC)
}

override fun schedulePeriodicFilesSyncJob() {
val request = periodicRequestBuilder(
jobClass = FilesSyncWork::class,
Expand Down
41 changes: 36 additions & 5 deletions app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,50 @@ class FilesSyncWork(
setForegroundAsync(foregroundInfo)
}

private fun canExitEarly(changedFiles: Array<String>?): Boolean {
var canExitEarly = false
// If we are in power save mode better to postpone scan and upload
val overridePowerSaving = inputData.getBoolean(OVERRIDE_POWER_SAVING, false)
if ((powerManagementService.isPowerSavingEnabled && !overridePowerSaving)) {
canExitEarly = true
}

// or sync worker already running and no changed files to be processed
val alreadyRunning = backgroundJobManager.bothFilesSyncJobsRunning()
if (alreadyRunning && changedFiles.isNullOrEmpty()) {
Log_OC.d(TAG, "File-sync kill worker since another instance of the worker seems to be running already!")
canExitEarly = true
}

if (!syncedFolderProvider.syncedFolders.any { it.isEnabled }) {
Log_OC.d(TAG, "File-sync kill worker since no sync folder is enabled!")
canExitEarly = true
}

if (syncedFolderProvider.syncedFolders.all { it.isChargingOnly } &&
!powerManagementService.battery.isCharging &&
!powerManagementService.battery.isFull
) {
Log_OC.d(TAG, "File-sync kill worker since phone is not charging!")
canExitEarly = true
}

return canExitEarly
}

@Suppress("MagicNumber")
override fun doWork(): Result {
backgroundJobManager.logStartOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class))
Log_OC.d(TAG, "File-sync worker started")

val overridePowerSaving = inputData.getBoolean(OVERRIDE_POWER_SAVING, false)
// If we are in power save mode, better to postpone upload
if (powerManagementService.isPowerSavingEnabled && !overridePowerSaving) {
val changedFiles = inputData.getStringArray(CHANGED_FILES)

if (canExitEarly(changedFiles)) {
val result = Result.success()
backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class), result)
return result
}

val resources = context.resources
val lightVersion = resources.getBoolean(R.bool.syncedFolder_light)
FilesSyncHelper.restartJobsIfNeeded(
Expand All @@ -113,7 +145,6 @@ class FilesSyncWork(
)

// Get changed files from ContentObserverWork (only images and videos) or by scanning filesystem
val changedFiles = inputData.getStringArray(CHANGED_FILES)
Log_OC.d(TAG, "File-sync worker changed files from observer: " + changedFiles.contentToString())
collectChangedFiles(changedFiles)
Log_OC.d(TAG, "File-sync worker finished checking files.")
Expand Down Expand Up @@ -157,7 +188,7 @@ class FilesSyncWork(
// Check every file in every synced folder for changes and update
// filesystemDataProvider database (potentially needs a long time so use foreground worker)
updateForegroundWorker(5, true)
FilesSyncHelper.insertAllDBEntries(syncedFolderProvider)
FilesSyncHelper.insertAllDBEntries(syncedFolderProvider, powerManagementService)
updateForegroundWorker(50, true)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,24 @@ import com.google.common.util.concurrent.ListenableFuture
import com.owncloud.android.lib.common.utils.Log_OC
import java.util.concurrent.ExecutionException

fun WorkManager.isWorkScheduled(tag: String): Boolean {
val statuses: ListenableFuture<List<WorkInfo>> = this.getWorkInfosByTag(tag)
var running = false
private const val TAG = "WorkManager"

fun WorkManager.isWorkRunning(tag: String): Boolean = checkWork(tag, listOf(WorkInfo.State.RUNNING))

fun WorkManager.isWorkScheduled(tag: String): Boolean =
checkWork(tag, listOf(WorkInfo.State.RUNNING, WorkInfo.State.ENQUEUED))

private fun WorkManager.checkWork(tag: String, stateConditions: List<WorkInfo.State>): Boolean {
val statuses: ListenableFuture<List<WorkInfo>> = getWorkInfosByTag(tag)
var workInfoList: List<WorkInfo> = emptyList()

try {
workInfoList = statuses.get()
} catch (e: ExecutionException) {
Log_OC.d("Worker", "ExecutionException in isWorkScheduled: $e")
Log_OC.d(TAG, "ExecutionException in checkWork: $e")
} catch (e: InterruptedException) {
Log_OC.d("Worker", "InterruptedException in isWorkScheduled: $e")
}

for (workInfo in workInfoList) {
val state = workInfo.state
running = running || (state == WorkInfo.State.RUNNING || state == WorkInfo.State.ENQUEUED)
Log_OC.d(TAG, "InterruptedException in checkWork: $e")
}

return running
return workInfoList.any { workInfo -> stateConditions.contains(workInfo.state) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,15 @@ private static void insertAllDBEntriesForSyncedFolder(SyncedFolder syncedFolder)
}
}

public static void insertAllDBEntries(SyncedFolderProvider syncedFolderProvider) {
public static void insertAllDBEntries(SyncedFolderProvider syncedFolderProvider,
PowerManagementService powerManagementService) {
for (SyncedFolder syncedFolder : syncedFolderProvider.getSyncedFolders()) {
if (syncedFolder.isEnabled()) {
if (syncedFolder.isEnabled() &&
!(syncedFolder.isChargingOnly() &&
!powerManagementService.getBattery().isCharging() &&
!powerManagementService.getBattery().isFull()
)
) {
insertAllDBEntriesForSyncedFolder(syncedFolder);
}
}
Expand Down

0 comments on commit f027458

Please sign in to comment.