瀏覽代碼

FilesUploadWorker: ensure only one worker can be running from the same user

Should fix problems with auto-conflicts, OOM, etc caused by several workers trying to upload the same file

Signed-off-by: Álvaro Brey <alvaro.brey@nextcloud.com>
Álvaro Brey 2 年之前
父節點
當前提交
bbb55b7f28

+ 1 - 1
app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt

@@ -455,7 +455,7 @@ internal class BackgroundJobManagerImpl(
             .setInputData(data)
             .setInputData(data)
             .build()
             .build()
 
 
-        workManager.enqueue(request)
+        workManager.enqueueUniqueWork(JOB_FILES_UPLOAD + user.accountName, ExistingWorkPolicy.KEEP, request)
     }
     }
 
 
     override fun getFileUploads(user: User): LiveData<List<JobInfo>> {
     override fun getFileUploads(user: User): LiveData<List<JobInfo>> {

+ 15 - 6
app/src/main/java/com/nextcloud/client/jobs/FilesUploadWorker.kt

@@ -27,7 +27,6 @@ import android.app.PendingIntent
 import android.content.Context
 import android.content.Context
 import android.content.Intent
 import android.content.Intent
 import android.os.Build
 import android.os.Build
-import android.text.TextUtils
 import androidx.core.app.NotificationCompat
 import androidx.core.app.NotificationCompat
 import androidx.localbroadcastmanager.content.LocalBroadcastManager
 import androidx.localbroadcastmanager.content.LocalBroadcastManager
 import androidx.work.Worker
 import androidx.work.Worker
@@ -74,14 +73,26 @@ class FilesUploadWorker(
 
 
     override fun doWork(): Result {
     override fun doWork(): Result {
         val accountName = inputData.getString(ACCOUNT)
         val accountName = inputData.getString(ACCOUNT)
-        if (TextUtils.isEmpty(accountName)) {
+        if (accountName.isNullOrEmpty()) {
             return Result.failure() // user account is needed
             return Result.failure() // user account is needed
         }
         }
 
 
+        // get all pending uploads
+        var currentAndPendingUploadsForAccount =
+            uploadsStorageManager.getCurrentAndPendingUploadsForAccount(accountName)
+        while (currentAndPendingUploadsForAccount.isNotEmpty()) {
+            handlePendingUploads(currentAndPendingUploadsForAccount, accountName)
+            currentAndPendingUploadsForAccount =
+                uploadsStorageManager.getCurrentAndPendingUploadsForAccount(accountName)
+        }
+
+        return Result.success()
+    }
+
+    private fun handlePendingUploads(uploads: Array<OCUpload>, accountName: String) {
         val user = userAccountManager.getUser(accountName)
         val user = userAccountManager.getUser(accountName)
 
 
-        // get all pending uploads
-        for (upload in uploadsStorageManager.getCurrentAndPendingUploadsForAccount(accountName!!)) {
+        for (upload in uploads) {
             // create upload file operation
             // create upload file operation
             if (user.isPresent) {
             if (user.isPresent) {
                 val uploadFileOperation = createUploadFileOperation(upload, user.get())
                 val uploadFileOperation = createUploadFileOperation(upload, user.get())
@@ -100,8 +111,6 @@ class FilesUploadWorker(
                 uploadsStorageManager.removeUpload(upload.uploadId)
                 uploadsStorageManager.removeUpload(upload.uploadId)
             }
             }
         }
         }
-
-        return Result.success()
     }
     }
 
 
     /**
     /**