From f840dd505f821e516b8f5894fc8c9c1e95ad6e41 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Fri, 14 Jul 2017 19:06:01 +0000 Subject: [PATCH] Simplified sync logging and reporting --- CliClient/app/command-sync.js | 11 +-- CliClient/app/vorpal-utils.js | 2 +- .../lib/components/side-menu-content.js | 12 +-- ReactNativeClient/lib/synchronizer.js | 98 +++++++------------ 4 files changed, 44 insertions(+), 79 deletions(-) diff --git a/CliClient/app/command-sync.js b/CliClient/app/command-sync.js index be6d8099b..fe2c85df2 100644 --- a/CliClient/app/command-sync.js +++ b/CliClient/app/command-sync.js @@ -22,14 +22,12 @@ class Command extends BaseCommand { } async action(args) { + let sync = await app().synchronizer(Setting.value('sync.target')); + let options = { onProgress: (report) => { - let line = []; - if (report.remotesToUpdate) line.push(_('Items to upload: %d/%d.', report.createRemote + report.updateRemote, report.remotesToUpdate)); - if (report.remotesToDelete) line.push(_('Remote items to delete: %d/%d.', report.deleteRemote, report.remotesToDelete)); - if (report.localsToUdpate) line.push(_('Items to download: %d/%d.', report.createLocal + report.updateLocal, report.localsToUdpate)); - if (report.localsToDelete) line.push(_('Local items to delete: %d/%d.', report.deleteLocal, report.localsToDelete)); - if (line.length) vorpalUtils.redraw(line.join(' ')); + let lines = sync.reportToLines(report); + if (lines.length) vorpalUtils.redraw(lines.join(' ')); }, onMessage: (msg) => { vorpalUtils.redrawDone(); @@ -40,7 +38,6 @@ class Command extends BaseCommand { this.log(_('Synchronization target: %s', Setting.value('sync.target'))); - let sync = await app().synchronizer(Setting.value('sync.target')); if (!sync) throw new Error(_('Cannot initialize synchronizer.')); this.log(_('Starting synchronization...')); diff --git a/CliClient/app/vorpal-utils.js b/CliClient/app/vorpal-utils.js index 7d032680f..c53a5348e 100644 --- a/CliClient/app/vorpal-utils.js +++ b/CliClient/app/vorpal-utils.js @@ -5,7 +5,7 @@ const vorpalUtils = {}; let vorpal_ = null; let redrawStarted_ = false; -let redrawLastUpdateTime_ = time.unixMs(); +let redrawLastUpdateTime_ = 0; let redrawLastLog_ = null; let redrawEnabled_ = true; let errorStackTraceEnabled_ = false; diff --git a/ReactNativeClient/lib/components/side-menu-content.js b/ReactNativeClient/lib/components/side-menu-content.js index 471ddbea8..99cc981a1 100644 --- a/ReactNativeClient/lib/components/side-menu-content.js +++ b/ReactNativeClient/lib/components/side-menu-content.js @@ -53,20 +53,16 @@ class SideMenuContentComponent extends Component { async synchronize_press() { if (reg.oneDriveApi().auth()) { + const sync = await reg.synchronizer() + let options = { onProgress: (report) => { - let line = []; - line.push(_('Items to upload: %d/%d.', report.createRemote + report.updateRemote, report.remotesToUpdate)); - line.push(_('Remote items to delete: %d/%d.', report.deleteRemote, report.remotesToDelete)); - line.push(_('Items to download: %d/%d.', report.createLocal + report.updateLocal, report.localsToUdpate)); - line.push(_('Local items to delete: %d/%d.', report.deleteLocal, report.localsToDelete)); - line.push(_('Sync state: %s.', report.state)); - this.setState({ syncReportText: line.join("\n") }); + let lines = sync.reportToLines(report); + this.setState({ syncReportText: lines.join("\n") }); }, }; try { - const sync = await reg.synchronizer() sync.start(options); } catch (error) { Log.error(error); diff --git a/ReactNativeClient/lib/synchronizer.js b/ReactNativeClient/lib/synchronizer.js index df7a53291..07bdf0b10 100644 --- a/ReactNativeClient/lib/synchronizer.js +++ b/ReactNativeClient/lib/synchronizer.js @@ -6,6 +6,7 @@ import { BaseModel } from 'lib/base-model.js'; import { sprintf } from 'sprintf-js'; import { time } from 'lib/time-utils.js'; import { Logger } from 'lib/logger.js' +import { _ } from 'lib/locale.js'; import moment from 'moment'; class Synchronizer { @@ -19,6 +20,9 @@ class Synchronizer { this.logger_ = new Logger(); this.appType_ = appType; this.cancelling_ = false; + + this.onProgress_ = function(s) {}; + this.progressReport_ = {}; } state() { @@ -41,10 +45,22 @@ class Synchronizer { return this.logger_; } - logSyncOperation(action, local, remote, reason) { + reportToLines(report) { + let lines = []; + if (report.createLocal) lines.push(_('Created local items: %d.', report.createLocal)); + if (report.updateLocal) lines.push(_('Updated local items: %d.', report.updateLocal)); + if (report.createRemote) lines.push(_('Created remote items: %d.', report.createRemote)); + if (report.updatedRemote) lines.push(_('Updated remote items: %d.', report.updatedRemote)); + if (report.deleteLocal) lines.push(_('Deleted local items: %d.', report.deleteLocal)); + if (report.deleteRemote) lines.push(_('Deleted remote items: %d.', report.deleteRemote)); + if (report.state) lines.push(_('State: %s.', report.state)); + return lines; + } + + logSyncOperation(action, local = null, remote = null, message = null) { let line = ['Sync']; line.push(action); - line.push(reason); + if (message) line.push(message); let type = local && local.type_ ? local.type_ : null; if (!type) type = remote && remote.type_ ? remote.type_ : null; @@ -66,9 +82,15 @@ class Synchronizer { } this.logger().debug(line.join(': ')); + + if (!this.progressReport_[action]) this.progressReport_[action] = 0; + this.progressReport_[action]++; + this.progressReport_.state = this.state(); + this.onProgress_(this.progressReport_); } async logSyncSummary(report) { + this.logger().info('Operations completed: '); for (let n in report) { if (!report.hasOwnProperty(n)) continue; if (n == 'errors') continue; @@ -81,11 +103,10 @@ class Synchronizer { this.logger().info('Total notes: ' + noteCount); this.logger().info('Total resources: ' + resourceCount); - if (report.errors.length) { + if (report.errors && report.errors.length) { this.logger().warn('There was some errors:'); for (let i = 0; i < report.errors.length; i++) { let e = report.errors[i]; - //let msg = JSON.stringify(e); //e && e.message ? e.message : JSON.stringify(e); this.logger().warn(e); } } @@ -115,7 +136,8 @@ class Synchronizer { async start(options = null) { if (!options) options = {}; - if (!options.onProgress) options.onProgress = function(o) {}; + this.onProgress_ = options.onProgress ? options.onProgress : function(o) {}; + this.progressReport_ = { errors: [] }; if (this.state() != 'idle') { this.logger().warn('Synchronization is already in progress. State: ' + this.state()); @@ -131,28 +153,10 @@ class Synchronizer { // ------------------------------------------------------------------------ let synchronizationId = time.unixMs().toString(); - this.logger().info('Starting synchronization... [' + synchronizationId + ']'); this.state_ = 'started'; - let report = { - remotesToUpdate: 0, - remotesToDelete: 0, - localsToUdpate: 0, - localsToDelete: 0, - - createLocal: 0, - updateLocal: 0, - deleteLocal: 0, - createRemote: 0, - updateRemote: 0, - deleteRemote: 0, - itemConflict: 0, - noteConflict: 0, - - state: this.state(), - errors: [], - }; + this.logSyncOperation('starting', null, null, 'Starting synchronization... [' + synchronizationId + ']'); try { await this.api().mkdir(this.syncDirName_); @@ -165,9 +169,6 @@ class Synchronizer { let result = await BaseItem.itemsThatNeedSync(); let locals = result.items; - report.remotesToUpdate += locals.length; - options.onProgress(report); - for (let i = 0; i < locals.length; i++) { if (this.cancelling()) break; @@ -273,11 +274,7 @@ class Synchronizer { } - report[action]++; - donePaths.push(path); - - options.onProgress(report); } if (!result.hasMore) break; @@ -288,8 +285,6 @@ class Synchronizer { // ------------------------------------------------------------------------ let deletedItems = await BaseItem.deletedItems(); - report.remotesToDelete = deletedItems.length; - options.onProgress(report); for (let i = 0; i < deletedItems.length; i++) { if (this.cancelling()) break; @@ -299,9 +294,6 @@ class Synchronizer { await this.api().delete(path); if (this.randomFailure(options, 3)) return; await BaseItem.remoteDeletedItem(item.item_id); - - report['deleteRemote']++; - options.onProgress(report); } // ------------------------------------------------------------------------ @@ -344,9 +336,6 @@ class Synchronizer { if (!action) continue; - report.localsToUdpate++; - options.onProgress(report); - if (action == 'createLocal' || action == 'updateLocal') { let content = await this.api().get(path); if (content === null) { @@ -367,17 +356,7 @@ class Synchronizer { if (newContent.type_ == BaseModel.TYPE_RESOURCE && action == 'createLocal') { let localResourceContentPath = Resource.fullPath(newContent); let remoteResourceContentPath = this.resourceDirName_ + '/' + newContent.id; - await this.api().get(remoteResourceContentPath, { path: localResourceContentPath, target: 'file' }); - - // if (this.appType_ == 'cli') { - // let remoteResourceContent = await this.api().get(remoteResourceContentPath, { encoding: 'binary' }); - // await Resource.setContent(newContent, remoteResourceContent); - // } else if (this.appType_ == 'mobile') { - // await this.api().get(remoteResourceContentPath, { path: localResourceContentPath, target: 'file' }); - // } else { - // throw new Error('Unknown appType: ' + this.appType_); - // } } await ItemClass.save(newContent, options); @@ -386,10 +365,6 @@ class Synchronizer { } else { this.logSyncOperation(action, local, remote, reason); } - - report[action]++; - - options.onProgress(report); } if (!listResult.hasMore) break; @@ -417,14 +392,10 @@ class Synchronizer { continue; } - report.localsToDelete++; - options.onProgress(report); this.logSyncOperation('deleteLocal', { id: item.id }, null, 'remote has been deleted'); let ItemClass = BaseItem.itemClass(item); await ItemClass.delete(item.id, { trackDeleted: false }); - report['deleteLocal']++; - options.onProgress(report); } } } @@ -442,8 +413,8 @@ class Synchronizer { } } } catch (error) { - report.errors.push(error); this.logger().error(error); + this.progressReport_.errors.push(error); } if (this.cancelling()) { @@ -451,13 +422,14 @@ class Synchronizer { this.cancelling_ = false; } - this.logger().info('Synchronization complete [' + synchronizationId + ']:'); - await this.logSyncSummary(report); - this.state_ = 'idle'; - report.state = this.state(); - options.onProgress(report); + this.logSyncOperation('finished', null, null, 'Synchronization finished [' + synchronizationId + ']'); + + await this.logSyncSummary(this.progressReport_); + + this.onProgress_ = function(s) {}; + this.progressReport_ = {}; } }