From e7b7b0d06e611a08268d2ebf62a36fc6718b2aef Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Thu, 1 Feb 2018 10:32:44 -0800 Subject: [PATCH] VACUUM the database at launch periodically to prevent fragmentation issues --- .../onboarding/lib/onboarding-helpers.es6 | 2 +- app/src/mailsync-process.es6 | 61 +++++++++++- app/static/db-migration.html | 92 +++++++++++++++++++ app/static/db-vacuum.html | 92 +++++++++++++++++++ mailsync | 2 +- 5 files changed, 243 insertions(+), 6 deletions(-) create mode 100644 app/static/db-migration.html create mode 100644 app/static/db-vacuum.html diff --git a/app/internal_packages/onboarding/lib/onboarding-helpers.es6 b/app/internal_packages/onboarding/lib/onboarding-helpers.es6 index 8354b245d..e0b1d4a0d 100644 --- a/app/internal_packages/onboarding/lib/onboarding-helpers.es6 +++ b/app/internal_packages/onboarding/lib/onboarding-helpers.es6 @@ -141,6 +141,6 @@ export async function finalizeAndValidateAccount(account) { // Test connections to IMAP and SMTP const proc = new MailsyncProcess(AppEnv.getLoadSettings(), IdentityStore.identity(), account); - const response = await proc.test(); + const { response } = await proc.test(); return new Account(response.account); } diff --git a/app/src/mailsync-process.es6 b/app/src/mailsync-process.es6 index 603f83b21..72a8ad8ba 100644 --- a/app/src/mailsync-process.es6 +++ b/app/src/mailsync-process.es6 @@ -52,11 +52,48 @@ export default class MailsyncProcess extends EventEmitter { constructor({ configDirPath, resourcePath, verbose }, identity, account) { super(); this.verbose = verbose; + this.resourcePath = resourcePath; this.configDirPath = configDirPath; this.account = account; this.identity = identity; this.binaryPath = path.join(resourcePath, 'mailsync').replace('app.asar', 'app.asar.unpacked'); this._proc = null; + this._win = null; + } + + _showStatusWindow(mode) { + if (this._win) return; + const { BrowserWindow } = require('electron'); + this._win = new BrowserWindow({ + width: 350, + height: 108, + show: false, + center: true, + resizable: false, + minimizable: false, + maximizable: false, + closable: false, + fullscreenable: false, + webPreferences: { nodeIntegration: false, javascript: false }, + }); + this._win.setContentSize(350, 90); + this._win.once('ready-to-show', () => { + this._win.show(); + }); + this._win.loadURL(`file://${this.resourcePath}/static/db-${mode}.html`); + } + + _closeStatusWindow() { + if (!this._win) return; + this._win.removeAllListeners('ready-to-show'); + this._win.setClosable(true); + this._win.hide(); + setTimeout(() => { + // don't know why this timeout is necessary but the app becomes unable to + // load Electron modules in the main process if we close immediately. + if (!this._win.isDestroyed()) this._win.close(); + this._win = null; + }); } _spawnProcess(mode) { @@ -86,7 +123,7 @@ export default class MailsyncProcess extends EventEmitter { } } - _spawnAndWait(mode) { + _spawnAndWait(mode, { onData } = {}) { return new Promise((resolve, reject) => { this._spawnProcess(mode); let buffer = Buffer.from([]); @@ -94,11 +131,13 @@ export default class MailsyncProcess extends EventEmitter { if (this._proc.stdout) { this._proc.stdout.on('data', data => { buffer += data; + if (onData) onData(data); }); } if (this._proc.stderr) { this._proc.stderr.on('data', data => { buffer += data; + if (onData) onData(data); }); } @@ -125,7 +164,7 @@ export default class MailsyncProcess extends EventEmitter { .pop(); const response = JSON.parse(lastLine); if (code === 0) { - resolve(response); + resolve({ response, buffer }); } else { let msg = LocalizedErrorStrings[response.error] || response.error; if (response.error_service) { @@ -241,8 +280,22 @@ export default class MailsyncProcess extends EventEmitter { } } - migrate() { - return this._spawnAndWait('migrate'); + async migrate() { + try { + console.log('Running database migrations'); + const { buffer } = await this._spawnAndWait('migrate', { + onData: data => { + const str = data.toString().toLowerCase(); + if (str.includes('running migration')) this._showStatusWindow('migration'); + if (str.includes('running vacuum')) this._showStatusWindow('vacuum'); + }, + }); + console.log(buffer.toString()); + this._closeStatusWindow(); + } catch (err) { + this._closeStatusWindow(); + throw err; + } } resetCache() { diff --git a/app/static/db-migration.html b/app/static/db-migration.html new file mode 100644 index 000000000..7f4e97e86 --- /dev/null +++ b/app/static/db-migration.html @@ -0,0 +1,92 @@ + + + + Updating Mailspring Database... + + + + +
+ Mailspring is upgrading your email database and will start momentarily... +
+
+
+
+ + diff --git a/app/static/db-vacuum.html b/app/static/db-vacuum.html new file mode 100644 index 000000000..7c95a23b8 --- /dev/null +++ b/app/static/db-vacuum.html @@ -0,0 +1,92 @@ + + + + Preparing Mailspring... + + + + +
+ Mailspring is optimizing your email database to save space and will start momentarily... +
+
+
+
+ + diff --git a/mailsync b/mailsync index abed89b38..f79cefcec 160000 --- a/mailsync +++ b/mailsync @@ -1 +1 @@ -Subproject commit abed89b38711760f01b56dc3611024b32e12d229 +Subproject commit f79cefcec98135e3fa27ff2c2e4f5f2e05a512bf