Browse Source

fix: refine sync logic

Gerald 8 years ago
parent
commit
7875286965
3 changed files with 51 additions and 51 deletions
  1. 49 49
      src/background/sync/base.js
  2. 1 1
      src/background/sync/dropbox.js
  3. 1 1
      src/background/sync/onedrive.js

+ 49 - 49
src/background/sync/base.js

@@ -1,7 +1,7 @@
 import { debounce, normalizeKeys, request, noop } from 'src/common';
 import { debounce, normalizeKeys, request, noop } from 'src/common';
 import getEventEmitter from '../utils/events';
 import getEventEmitter from '../utils/events';
 import { getOption, setOption, hookOptions } from '../utils/options';
 import { getOption, setOption, hookOptions } from '../utils/options';
-import { getScriptsByIndex, parseScript, saveScript, removeScript } from '../utils/db';
+import { getScriptsByIndex, parseScript, removeScript } from '../utils/db';
 
 
 const serviceNames = [];
 const serviceNames = [];
 const services = {};
 const services = {};
@@ -282,48 +282,60 @@ export const BaseService = serviceFactory({
       total: 0,
       total: 0,
     };
     };
     this.syncState.set('syncing');
     this.syncState.set('syncing');
+    // Avoid simultaneous requests
     return this.getMeta()
     return this.getMeta()
-    .then(meta => Promise.all([
-      meta,
+    .then(remoteMeta => Promise.all([
+      remoteMeta,
       this.list(),
       this.list(),
       getScriptsByIndex('position'),
       getScriptsByIndex('position'),
     ]))
     ]))
-    .then(([meta, remoteData, localData]) => {
-      const remote = {
-        meta,
-        data: remoteData,
-      };
-      const local = {
-        meta: this.config.get('meta', {}),
-        data: localData,
-      };
-      const firstSync = !local.meta.timestamp;
-      const outdated = !local.meta.timestamp || remote.meta.timestamp > local.meta.timestamp;
+    .then(([remoteMeta, remoteData, localData]) => {
+      const remoteMetaInfo = remoteMeta.info || {};
+      let remoteChanged = !remoteMeta.timestamp || Object.keys(remoteMetaInfo).length !== remoteData.length;
+      const now = Date.now();
+      const remoteItemMap = {};
+      remoteMeta.info = remoteData.reduce((info, item) => {
+        remoteItemMap[item.uri] = item;
+        info[item.uri] = remoteMetaInfo[item.uri];
+        let itemInfo = info[item.uri];
+        if (!itemInfo) {
+          itemInfo = {};
+          info[item.uri] = itemInfo;
+          remoteChanged = true;
+        }
+        if (!itemInfo.modified) {
+          itemInfo.modified = now;
+          remoteChanged = true;
+        }
+        return info;
+      }, {});
+      const localMeta = this.config.get('meta', {});
+      const firstSync = !localMeta.timestamp;
+      const outdated = !localMeta.timestamp || remoteMeta.timestamp > localMeta.timestamp;
       this.log('First sync:', firstSync);
       this.log('First sync:', firstSync);
-      this.log('Outdated:', outdated, '(', 'local:', local.meta.timestamp, 'remote:', remote.meta.timestamp, ')');
-      const map = {};
+      this.log('Outdated:', outdated, '(', 'local:', localMeta.timestamp, 'remote:', remoteMeta.timestamp, ')');
       const getRemote = [];
       const getRemote = [];
       const putRemote = [];
       const putRemote = [];
       const delRemote = [];
       const delRemote = [];
       const delLocal = [];
       const delLocal = [];
-      remote.data.forEach(item => { map[item.uri] = item; });
-      local.data.forEach(item => {
-        const remoteItem = map[item.uri];
-        if (remoteItem) {
-          if (firstSync || !item.custom.modified || remoteItem.modified > item.custom.modified) {
+      localData.forEach(item => {
+        const remoteInfo = remoteMeta.info[item.uri];
+        if (remoteInfo) {
+          if (firstSync || !item.custom.modified || remoteInfo.modified > item.custom.modified) {
+            const remoteItem = remoteItemMap[item.uri];
             getRemote.push(remoteItem);
             getRemote.push(remoteItem);
-          } else if (remoteItem.modified < item.custom.modified) {
+          } else if (remoteInfo.modified < item.custom.modified) {
             putRemote.push(item);
             putRemote.push(item);
           }
           }
-          delete map[item.uri];
+          delete remoteItemMap[item.uri];
         } else if (firstSync || !outdated) {
         } else if (firstSync || !outdated) {
           putRemote.push(item);
           putRemote.push(item);
         } else {
         } else {
           delLocal.push(item);
           delLocal.push(item);
         }
         }
       });
       });
-      Object.keys(map).forEach(uri => {
-        const item = map[uri];
+      Object.keys(remoteItemMap).forEach(uri => {
+        const item = remoteItemMap[uri];
         if (outdated) {
         if (outdated) {
           getRemote.push(item);
           getRemote.push(item);
         } else {
         } else {
@@ -345,7 +357,7 @@ export const BaseService = serviceFactory({
             } catch (e) {
             } catch (e) {
               data.code = raw;
               data.code = raw;
             }
             }
-            data.modified = item.modified;
+            data.modified = remoteMeta.info[item.uri].modified;
             if (!getOption('syncScriptStatus') && data.more) {
             if (!getOption('syncScriptStatus') && data.more) {
               delete data.more.enabled;
               delete data.more.enabled;
             }
             }
@@ -364,16 +376,14 @@ export const BaseService = serviceFactory({
               update: item.update,
               update: item.update,
             },
             },
           });
           });
-          return this.put(getFilename(item.uri), data)
-          .then(res => {
-            if (item.custom.modified !== res.modified) {
-              item.custom.modified = res.modified;
-              return saveScript(item);
-            }
-          });
+          remoteMeta.info[item.uri] = { modified: item.custom.modified };
+          remoteChanged = true;
+          return this.put(getFilename(item.uri), data);
         }),
         }),
         delRemote.map(item => {
         delRemote.map(item => {
           this.log('Remove remote script:', item.uri);
           this.log('Remove remote script:', item.uri);
+          delete remoteMeta.info[item.uri];
+          remoteChanged = true;
           return this.remove(getFilename(item.uri));
           return this.remove(getFilename(item.uri));
         }),
         }),
         delLocal.map(item => {
         delLocal.map(item => {
@@ -383,23 +393,13 @@ export const BaseService = serviceFactory({
       );
       );
       promiseQueue.push(Promise.all(promiseQueue).then(() => {
       promiseQueue.push(Promise.all(promiseQueue).then(() => {
         const promises = [];
         const promises = [];
-        let remoteChanged;
-        if (!remote.meta.timestamp || putRemote.length || delRemote.length) {
-          remoteChanged = true;
-          remote.meta.timestamp = Date.now();
-          promises.push(this.put(this.metaFile, JSON.stringify(remote.meta)));
-        }
-        if (
-          !local.meta.timestamp
-          || getRemote.length
-          || delLocal.length
-          || remoteChanged
-          || outdated
-        ) {
-          local.meta.timestamp = remote.meta.timestamp;
+        if (remoteChanged) {
+          remoteMeta.timestamp = Date.now();
+          promises.push(this.put(this.metaFile, JSON.stringify(remoteMeta)));
         }
         }
-        local.meta.lastSync = Date.now();
-        this.config.set('meta', local.meta);
+        localMeta.timestamp = remoteMeta.timestamp;
+        localMeta.lastSync = Date.now();
+        this.config.set('meta', localMeta);
         return Promise.all(promises);
         return Promise.all(promises);
       }));
       }));
       // ignore errors to ensure all promises are fulfilled
       // ignore errors to ensure all promises are fulfilled

+ 1 - 1
src/background/sync/dropbox.js

@@ -124,7 +124,7 @@ function normalize(item) {
   return {
   return {
     size: item.size,
     size: item.size,
     uri: getURI(item.name),
     uri: getURI(item.name),
-    modified: new Date(item.server_modified).getTime(),
+    // modified: new Date(item.server_modified).getTime(),
     // isDeleted: item.is_deleted,
     // isDeleted: item.is_deleted,
   };
   };
 }
 }

+ 1 - 1
src/background/sync/onedrive.js

@@ -162,6 +162,6 @@ function normalize(item) {
   return {
   return {
     size: item.size,
     size: item.size,
     uri: getURI(item.name),
     uri: getURI(item.name),
-    modified: new Date(item.lastModifiedDateTime).getTime(),
+    // modified: new Date(item.lastModifiedDateTime).getTime(),
   };
   };
 }
 }