Эх сурвалжийг харах

Доработки, оптимизация сохранения recentLast

Book Pauk 6 жил өмнө
parent
commit
f648bcda13

+ 74 - 4
client/components/Reader/ServerStorage/ServerStorage.vue

@@ -50,6 +50,7 @@ class ServerStorage extends Vue {
         this.oldSettings = {};
         this.oldRecent = {};
         this.oldRecentLast = {};
+        this.oldRecentLastDiff = {};
     }
 
     async init() {
@@ -353,13 +354,15 @@ class ServerStorage extends Vue {
 
         const oldRev = bookManager.recentRev;
         const oldLastRev = bookManager.recentLastRev;
+        const oldLastDiffRev = bookManager.recentLastDiffRev;
         //проверим ревизию на сервере
         let revs = null;
         if (!force) {
             try {
-                revs = await this.storageCheck({recent: {}, recentLast: {}});
+                revs = await this.storageCheck({recent: {}, recentLast: {}, recentLastDiff: {}});
                 if (revs.state == 'success' && revs.items.recent.rev == oldRev &&
-                    revs.items.recentLast.rev == oldLastRev) {
+                    revs.items.recentLast.rev == oldLastRev &&
+                    revs.items.recentLastDiff.rev == oldLastDiffRev) {
                     return;
                 }
             } catch(e) {
@@ -391,24 +394,30 @@ class ServerStorage extends Vue {
             }
         }
 
-        if (force || revs.items.recentLast.rev != oldLastRev) {
+        if (force || revs.items.recentLast.rev != oldLastRev || revs.items.recentLastDiff.rev != oldLastDiffRev) {
             let recentLast = null;
             try {
-                recentLast = await this.storageGet({recentLast: {}});
+                recentLast = await this.storageGet({recentLast: {}, recentLastDiff: {}});
             } catch(e) {
                 this.error(`Ошибка соединения с сервером: ${e.message}`);
                 return;
             }
 
             if (recentLast.state == 'success') {
+                const recentLastDiff = recentLast.items.recentLastDiff;
                 recentLast = recentLast.items.recentLast;
 
                 if (recentLast.rev == 0)
                     recentLast.data = {};
+                if (recentLastDiff.rev == 0)
+                    recentLastDiff.data = {};
+
+                recentLast.data = utils.applyObjDiff(recentLast.data, recentLastDiff.data);
 
                 this.oldRecentLast = _.cloneDeep(recentLast.data);
                 await bookManager.setRecentLast(recentLast.data);
                 await bookManager.setRecentLastRev(recentLast.rev);
+                await bookManager.setRecentLastDiffRev(recentLastDiff.rev);
             } else {
                 this.warning(`Неверный ответ сервера: ${recentLast.state}`);
             }
@@ -476,6 +485,11 @@ class ServerStorage extends Vue {
         if (utils.isEmptyObjDiff(diff))
             return;
 
+        if (JSON.stringify(recentLast) > JSON.stringify(diff)) {
+            await this.saveRecentLastDiff(diff, force);
+            return;
+        }
+
         this.savingRecentLast = true;
         try {
             let result = {state: ''};
@@ -521,6 +535,62 @@ class ServerStorage extends Vue {
         }
     }
 
+    async saveRecentLastDiff(diff, force = false) {
+        if (!this.keyInited || !this.serverSyncEnabled || this.savingRecentLastDiff)
+            return;
+
+        const bm = bookManager;
+        let lastRev = bm.recentLastDiffRev;
+
+        const d = utils.getObjDiff(this.oldRecentLastDiff, diff);
+        if (utils.isEmptyObjDiff(d))
+            return;
+
+        this.savingRecentLastDiff = true;
+        try {
+            let result = {state: ''};
+            let tries = 0;
+            while (result.state != 'success' && tries < maxSetTries) {
+                if (force) {
+                    try {
+                        const revs = await this.storageCheck({recentLastDiff: {}});
+                        if (revs.items.recentLastDiff.rev)
+                            lastRev = revs.items.recentLastDiff.rev;
+                    } catch(e) {
+                        this.error(`Ошибка соединения с сервером: ${e.message}`);
+                        return;
+                    }
+                }
+
+                try {
+                    result = await this.storageSet({recentLastDiff: {rev: lastRev + 1, data: diff}}, force);
+                } catch(e) {
+                    this.savingRecentLastDiff = false;
+                    this.error(`Ошибка соединения с сервером: (${e.message}). Изменения не сохранены.`);
+                    return;
+                }
+
+                if (result.state == 'reject') {
+                    await this.loadRecent(false);
+                    this.savingRecentLastDiff = false;
+                    return;
+                }
+
+                tries++;
+            }
+
+            if (tries >= maxSetTries) {
+                console.error(result);
+                this.error('Не удалось отправить данные на сервер. Данные не сохранены и могут быть перезаписаны.');
+            } else {
+                this.oldRecentLastDiff = _.cloneDeep(diff);
+                await bm.setRecentLastDiffRev(lastRev + 1);
+            }
+        } finally {
+            this.savingRecentLastDiff = false;
+        }
+    }
+
     async storageCheck(items) {
         return await this.storageApi('check', items);
     }

+ 7 - 1
client/components/Reader/share/bookManager.js

@@ -38,6 +38,7 @@ class BookManager {
             this.recent[this.recentLast.key] = this.recentLast;
         this.recentRev = await bmRecentStore.getItem('recent-rev') || 0;
         this.recentLastRev = await bmRecentStore.getItem('recent-last-rev') || 0;
+        this.recentLastDiffRev = await bmRecentStore.getItem('recent-last-diff-rev') || 0;
         this.books = Object.assign({}, this.booksCached);
 
         this.recentChanged2 = true;
@@ -428,10 +429,15 @@ class BookManager {
     }
 
     async setRecentLastRev(value) {
-        bmRecentStore.setItem('recent-last-rev', value);
+        await bmRecentStore.setItem('recent-last-rev', value);
         this.recentLastRev = value;
     }
 
+    async setRecentLastDiffRev(value) {
+        await bmRecentStore.setItem('recent-last-diff-rev', value);
+        this.recentLastDiffRev = value;
+    }
+
     addEventListener(listener) {
         if (this.eventListeners.indexOf(listener) < 0)
             this.eventListeners.push(listener);