Browse Source

Work a bit on locking

Signed-off-by: Mario Danic <mario@lovelyhq.com>
Mario Danic 8 years ago
parent
commit
4efb17fd1d

+ 1 - 1
build.gradle

@@ -187,7 +187,7 @@ dependencies {
     compile 'com.github.tobiasKaminsky:android-floating-action-button:1.10.2'
     compile 'com.google.code.findbugs:annotations:2.0.1'
     compile group: 'commons-io', name: 'commons-io', version: '2.4'
-    compile 'com.github.evernote:android-job:v1.1.9'
+    compile 'com.github.evernote:android-job:v1.1.10'
     compile 'com.jakewharton:butterknife:8.4.0'
     annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
     compile 'org.greenrobot:eventbus:3.0.0'

+ 11 - 1
src/main/java/com/owncloud/android/datamodel/FileSystemDataSet.java

@@ -29,17 +29,20 @@ public class FileSystemDataSet {
     private boolean isFolder;
     private boolean isSentForUpload;
     private long foundAt;
+    private boolean isFileModified;
 
     public FileSystemDataSet() {
     }
 
-    public FileSystemDataSet(int id, String localPath, long modifiedAt, boolean isFolder, boolean isSentForUpload, long foundAt) {
+    public FileSystemDataSet(int id, String localPath, long modifiedAt, boolean isFolder,
+                             boolean isSentForUpload, long foundAt, boolean isFileModified) {
         this.id = id;
         this.localPath = localPath;
         this.modifiedAt = modifiedAt;
         this.isFolder = isFolder;
         this.isSentForUpload = isSentForUpload;
         this.foundAt = foundAt;
+        this.isFileModified = isFileModified;
     }
 
     public int getId() {
@@ -90,4 +93,11 @@ public class FileSystemDataSet {
         isSentForUpload = sentForUpload;
     }
 
+    public boolean isFileModified() {
+        return isFileModified;
+    }
+
+    public void setFileModified(boolean fileModified) {
+        isFileModified = fileModified;
+    }
 }

+ 24 - 9
src/main/java/com/owncloud/android/datamodel/FilesystemDataProvider.java

@@ -61,7 +61,7 @@ public class FilesystemDataProvider {
         }
     }
 
-    public void storeOrUpdateFileValue(String localPath, long modifiedAt, boolean isFolder, boolean sentForUpload) {
+    public void storeOrUpdateFileValue(String localPath, long modifiedAt, boolean isFolder, boolean fileBeingModified) {
         FileSystemDataSet data = getFilesystemDataSet(localPath);
 
         int isFolderValue = 0;
@@ -69,20 +69,23 @@ public class FilesystemDataProvider {
             isFolderValue = 1;
         }
 
-        int isSentForUpload = 0;
-        if (sentForUpload) {
-            isSentForUpload = 1;
+        int isBeingModified = 0;
+        if (fileBeingModified) {
+            isBeingModified = 1;
         }
 
         ContentValues cv = new ContentValues();
-        cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH, localPath);
-        cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_MODIFIED, modifiedAt);
-        cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_IS_FOLDER, isFolderValue);
         cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_FOUND_RECENTLY, System.currentTimeMillis());
-        cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD, isSentForUpload);
+        cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_BEING_MODIFIED, isBeingModified);
 
         if (data == null) {
 
+            cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH, localPath);
+            cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_MODIFIED, modifiedAt);
+            cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_IS_FOLDER, isFolderValue);
+            cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD, 0);
+
+
             Uri result = contentResolver.insert(ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM, cv);
 
             if (result == null) {
@@ -90,6 +93,10 @@ public class FilesystemDataProvider {
             }
         } else {
 
+            if (data.getModifiedAt() != modifiedAt) {
+                cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD, 0);
+            }
+
             int result = contentResolver.update(
                     ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
                     cv,
@@ -134,10 +141,18 @@ public class FilesystemDataProvider {
                     isSentForUpload = true;
                 }
 
+                boolean isBeingModified = false;
+                if (cursor.getInt(cursor.getColumnIndex(
+                        ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_BEING_MODIFIED)) != 0) {
+                    isBeingModified = true;
+                }
+
+
                 if (id == -1) {
                     Log_OC.e(TAG, "Arbitrary value could not be created from cursor");
                 } else {
-                    dataSet = new FileSystemDataSet(id, localPath, modifiedAt, isFolder, isSentForUpload, foundAt);
+                    dataSet = new FileSystemDataSet(id, localPath, modifiedAt, isFolder, isSentForUpload, foundAt,
+                            isBeingModified);
                 }
             }
             cursor.close();

+ 1 - 0
src/main/java/com/owncloud/android/db/ProviderMeta.java

@@ -208,5 +208,6 @@ public class ProviderMeta {
         public static final String FILESYSTEM_FILE_IS_FOLDER = "is_folder";
         public static final String FILESYSTEM_FILE_FOUND_RECENTLY = "found_at";
         public static final String FILESYSTEM_FILE_SENT_FOR_UPLOAD = "upload_triggered";
+        public static final String FILESYSTEM_FILE_BEING_MODIFIED = "file_being_modified";
     }
 }

+ 20 - 2
src/main/java/com/owncloud/android/jobs/NewAutoUploadJob.java

@@ -41,7 +41,12 @@ import org.lukhnos.nnio.file.Paths;
 import org.lukhnos.nnio.file.SimpleFileVisitor;
 import org.lukhnos.nnio.file.attribute.BasicFileAttributes;
 
+import java.io.File;
 import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.channels.OverlappingFileLockException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -85,6 +90,7 @@ public class NewAutoUploadJob extends Job {
         List<SyncedFolder> syncedFolders = syncedFolderProvider.getSyncedFolders();
         List<SyncedFolder> syncedFoldersToDelete = new ArrayList<>();
 
+        // be smart, and only traverse folders once instead of multiple times
         for (SyncedFolder syncedFolder : syncedFolders) {
             for (SyncedFolder secondarySyncedFolder : syncedFolders) {
                 if (!syncedFolder.equals(secondarySyncedFolder) &&
@@ -98,6 +104,7 @@ public class NewAutoUploadJob extends Job {
         // delete all the folders from the list that we won't traverse
         syncedFolders.removeAll(syncedFoldersToDelete);
 
+        // store all files from the filesystem
         for (int i = 0; i < syncedFolders.size(); i++) {
             Path path = Paths.get(syncedFolders.get(i).getLocalPath());
 
@@ -106,8 +113,19 @@ public class NewAutoUploadJob extends Job {
                     @Override
                     public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
 
-                        filesystemDataProvider.storeOrUpdateFileValue(path.toAbsolutePath().toString(),
-                                attrs.lastModifiedTime().toMillis(), path.toFile().isDirectory(), false);
+                        File file = path.toFile();
+                        FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
+                        FileLock lock = channel.lock();
+                        try {
+                            lock = channel.tryLock();
+                            filesystemDataProvider.storeOrUpdateFileValue(path.toAbsolutePath().toString(),
+                                    attrs.lastModifiedTime().toMillis(), file.isDirectory(), false);
+                        } catch (OverlappingFileLockException e) {
+                            filesystemDataProvider.storeOrUpdateFileValue(path.toAbsolutePath().toString(),
+                                    attrs.lastModifiedTime().toMillis(), file.isDirectory(), true);
+                        } finally {
+                            lock.release();
+                        }
 
                         return FileVisitResult.CONTINUE;
                     }

+ 1 - 0
src/main/java/com/owncloud/android/providers/FileContentProvider.java

@@ -1247,6 +1247,7 @@ public class FileContentProvider extends ContentProvider {
                 + ProviderTableMeta.FILESYSTEM_FILE_IS_FOLDER + " INTEGER, "
                 + ProviderTableMeta.FILESYSTEM_FILE_FOUND_RECENTLY + " LONG, "
                 + ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD + " INTEGER, "
+                + ProviderTableMeta.FILESYSTEM_FILE_BEING_MODIFIED + " INTEGER, "
                 + ProviderTableMeta.FILESYSTEM_FILE_MODIFIED + " LONG );"
         );
     }