From f124b9c050c09c6d174e5af9e9bb5a93e7b40667 Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Fri, 20 Sep 2019 16:29:19 +0700 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D0=BA=D0=B8=20=D1=81=D0=B8=D0=BD=D1=85=D1=80=D0=BE=D0=BD=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D0=B8,=20=D0=B7=D0=B0=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20diff=20=D0=BD=D0=B0=20delta?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reader/ServerStorage/ServerStorage.vue | 188 +++++++++--------- client/components/Reader/share/bookManager.js | 9 +- 2 files changed, 95 insertions(+), 102 deletions(-) diff --git a/client/components/Reader/ServerStorage/ServerStorage.vue b/client/components/Reader/ServerStorage/ServerStorage.vue index 9c9aa7ca..1daa7680 100644 --- a/client/components/Reader/ServerStorage/ServerStorage.vue +++ b/client/components/Reader/ServerStorage/ServerStorage.vue @@ -72,7 +72,8 @@ class ServerStorage extends Vue { async bookManagerEvent(eventName, itemKey) { if (eventName == 'recent-changed') { - this.debouncedSaveRecent(itemKey); + if (itemKey) + this.debouncedSaveRecent(itemKey); } } @@ -103,7 +104,7 @@ class ServerStorage extends Vue { await this.loadProfiles(force); this.checkCurrentProfile(); await this.currentProfileChanged(force); - await this.loadRecent(force); + await this.loadRecent(); if (force) await this.saveRecent(); } @@ -324,66 +325,89 @@ class ServerStorage extends Vue { } } - async loadRecent(force = false, doNotifySuccess = true) { + async initRecentDelta() { + let recentDelta = null; + try { + recentDelta = await this.storageGet({recentDelta: {}}); + } catch(e) { + this.error(`Ошибка соединения с сервером: ${e.message}`); + return; + } + + if (recentDelta.state == 'success') { + recentDelta = recentDelta.items.recentDelta; + + if (recentDelta.rev == 0) + recentDelta.data = {}; + + this.recentDelta = recentDelta.data; + this.recentDeltaInited = true; + } else { + this.warning(`Неверный ответ сервера: ${recentDelta.state}`); + } + } + + async loadRecent(doNotifySuccess = true) { if (!this.keyInited || !this.serverSyncEnabled) return; const oldRecentRev = bookManager.recentRev; - const oldRecentDiffRev = bookManager.recentDiffRev; + const oldRecentDeltaRev = bookManager.recentDeltaRev; //проверим ревизию на сервере let revs = null; - if (!force) { - try { - revs = await this.storageCheck({recent: {}, recentDiff: {}}); - if (revs.state == 'success' && revs.items.recent.rev == oldRecentRev && - revs.items.recentDiff.rev == oldRecentDiffRev) { - return; - } - } catch(e) { - this.error(`Ошибка соединения с сервером: ${e.message}`); + try { + revs = await this.storageCheck({recent: {}, recentDelta: {}}); + if (revs.state == 'success' && revs.items.recent.rev == oldRecentRev && + revs.items.recentDelta.rev == oldRecentDeltaRev) { + if (!this.recentDeltaInited) + await this.initRecentDelta(); return; } + } catch(e) { + this.error(`Ошибка соединения с сервером: ${e.message}`); + return; } let recent = null; - if (force || revs.items.recent.rev != oldRecentRev || revs.items.recentDiff.rev != oldRecentDiffRev) { - try { - recent = await this.storageGet({recent: {}, recentDiff: {}}); - } catch(e) { - this.error(`Ошибка соединения с сервером: ${e.message}`); - return; - } - - if (recent.state == 'success') { - let recentDiff = recent.items.recentDiff; - recent = recent.items.recent; - - if (recent.rev == 0) - recent.data = {}; - - this.oldRecent = _.cloneDeep(recent.data); - let newRecent = {}; - if (recentDiff && recentDiff.data) { - newRecent = utils.applyObjDiff(recent.data, recentDiff.data); - this.recentDiff = _.cloneDeep(recentDiff.data); - if (!utils.isObjDiff(this.recentDiff)) - this.recentDiff = null; - } else { - newRecent = recent.data; - this.recentDiff = null; - } - - - if (!bookManager.loaded) { - this.warning('Ожидание загрузки списка книг перед синхронизацией'); - while (!bookManager.loaded) await utils.sleep(100); - } - await bookManager.setRecent(newRecent); - await bookManager.setRecentRev(recent.rev); - await bookManager.setRecentDiffRev(recentDiff.rev); + try { + if (revs.items.recent.rev != oldRecentRev) { + recent = await this.storageGet({recent: {}, recentDelta: {}}); } else { - this.warning(`Неверный ответ сервера: ${recent.state}`); + recent = await this.storageGet({recentDelta: {}}); + recent.items.recent = {data: _.cloneDeep(bookManager.recent), rev: oldRecentRev}; } + } catch(e) { + this.error(`Ошибка соединения с сервером: ${e.message}`); + return; + } + + if (recent.state == 'success') { + let recentDelta = recent.items.recentDelta; + recent = recent.items.recent; + + if (recent.rev == 0) + recent.data = {}; + + let newRecent = {}; + if (recentDelta && recentDelta.data) { + newRecent = Object.assign(recent.data, recentDelta.data); + this.recentDelta = recentDelta.data; + } else { + newRecent = recent.data; + this.recentDelta = null; + } + + this.recentDeltaInited = true; + + if (!bookManager.loaded) { + this.warning('Ожидание загрузки списка книг перед синхронизацией'); + while (!bookManager.loaded) await utils.sleep(100); + } + await bookManager.setRecent(newRecent); + await bookManager.setRecentRev(recent.rev); + await bookManager.setRecentDeltaRev(recentDelta.rev); + } else { + this.warning(`Неверный ответ сервера: ${recent.state}`); } if (doNotifySuccess) @@ -396,77 +420,43 @@ class ServerStorage extends Vue { const bm = bookManager; - /*if (!bookManager.loaded) { + if (!this.recentDeltaInited) { this.warning('Функции сохранения на сервер пока недоступны'); return; - }*/ - - //несколько замудреная инициализация oldRecent - if (!this.oldRecent) { - this.oldRecent = _.cloneDeep(bookManager.recent); } - if (bookManager.loaded && !this.oldRecentInited) { - this.oldRecent = _.cloneDeep(bookManager.recent); - this.oldRecentInited = true; - } + if (!this.recentDelta) + this.recentDelta = {}; - //вычисляем дифф - let diff = null; - if (itemKey) {//ускоренное вычисления диффа - let itemDiff; - if (this.oldRecent[itemKey]) { - itemDiff = utils.getObjDiff({[itemKey]: (this.oldRecentInited ? this.oldRecent[itemKey] : {})}, {[itemKey]: bm.recent[itemKey]}); - } else { - itemDiff = utils.getObjDiff({}, {[itemKey]: bm.recent[itemKey]}); - } - if (this.recentDiff) { - diff = this.recentDiff; - if (itemDiff.change[itemKey]) - diff.change[itemKey] = itemDiff.change[itemKey]; - if (itemDiff.add[itemKey]) - diff.add[itemKey] = itemDiff.add[itemKey]; - } else { - diff = itemDiff; - } - } else {//медленное вычисление диффа - if (this.oldRecentInited) { - diff = utils.getObjDiff(this.oldRecent, bm.recent); - } else - return; - } - - if (utils.isEmptyObjDiff(diff)) - return; + this.recentDelta[itemKey] = _.cloneDeep(bm.recent[itemKey]); //вычисление критерия сохранения целиком - let forceSaveRecent = JSON.stringify(diff).length > 2000; + let forceSaveRecent = false; if (!forceSaveRecent && itemKey) { if (!this.sameKeyCount) this.sameKeyCount = 0; if (this.prevItemKey == itemKey) this.sameKeyCount++; - forceSaveRecent = this.sameKeyCount > 5 && (Object.keys(diff.change).length > 1); + forceSaveRecent = this.sameKeyCount > 5 && (Object.keys(this.recentDelta).length > 1); this.sameKeyCount = (!forceSaveRecent ? this.sameKeyCount : 0); this.prevItemKey = itemKey; } - this.recentDiff = diff; this.savingRecent = true; try { if (forceSaveRecent) {//сохраняем recent целиком let result = {state: ''}; try { - result = await this.storageSet({recent: {rev: bm.recentRev + 1, data: bm.recent}, recentDiff: {rev: bm.recentDiffRev + 1, data: {}}}); + result = await this.storageSet({recent: {rev: bm.recentRev + 1, data: bm.recent}, recentDelta: {rev: bm.recentDeltaRev + 1, data: {}}}); } catch(e) { this.error(`Ошибка соединения с сервером (${e.message}). Данные не сохранены и могут быть перезаписаны.`); } if (result.state == 'reject') { - await this.loadRecent(true, false); + await this.loadRecent(false); this.warning(`Последние изменения отменены. Данные синхронизированы с сервером.`); if (!recurse) { this.savingRecent = false; @@ -474,25 +464,29 @@ class ServerStorage extends Vue { return; } } else if (result.state == 'success') { - this.oldRecent = _.cloneDeep(bm.recent); - this.recentDiff = null; + this.recentDelta = null; await bm.setRecentRev(bm.recentRev + 1); - await bm.setRecentDiffRev(bm.recentDiffRev + 1); + await bm.setRecentDeltaRev(bm.recentDeltaRev + 1); } } else {//сохраняем только дифф let result = {state: ''}; try { - result = await this.storageSet({recentDiff: {rev: bm.recentDiffRev + 1, data: this.recentDiff}}); + result = await this.storageSet({recentDelta: {rev: bm.recentDeltaRev + 1, data: this.recentDelta}}); } catch(e) { this.error(`Ошибка соединения с сервером (${e.message}). Данные не сохранены и могут быть перезаписаны.`); } if (result.state == 'reject') { - await this.loadRecent(true, false); + await this.loadRecent(false); this.warning(`Последние изменения отменены. Данные синхронизированы с сервером.`); + if (!recurse) { + this.savingRecent = false; + this.saveRecent(itemKey, true); + return; + } } else if (result.state == 'success') { - await bm.setRecentDiffRev(bm.recentDiffRev + 1); + await bm.setRecentDeltaRev(bm.recentDeltaRev + 1); } } } finally { diff --git a/client/components/Reader/share/bookManager.js b/client/components/Reader/share/bookManager.js index 2905b1e9..a00ee395 100644 --- a/client/components/Reader/share/bookManager.js +++ b/client/components/Reader/share/bookManager.js @@ -37,7 +37,7 @@ class BookManager { } this.recentRev = await bmRecentStore.getItem('recent-rev') || 0; - this.recentDiffRev = await bmRecentStore.getItem('recent-diff-rev') || 0; + this.recentDeltaRev = await bmRecentStore.getItem('recent-delta-rev') || 0; this.recentChanged = true; @@ -459,12 +459,11 @@ class BookManager { this.recentRev = value; } - async setRecentDiffRev(value) { - await bmRecentStore.setItem('recent-diff-rev', value); - this.recentDiffRev = value; + async setRecentDeltaRev(value) { + await bmRecentStore.setItem('recent-delta-rev', value); + this.recentDeltaRev = value; } - addEventListener(listener) { if (this.eventListeners.indexOf(listener) < 0) this.eventListeners.push(listener);