VACUUM the database at launch periodically to prevent fragmentation issues

This commit is contained in:
Ben Gotow 2018-02-01 10:32:44 -08:00
parent a440964c39
commit e7b7b0d06e
5 changed files with 243 additions and 6 deletions

View file

@ -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);
}

View file

@ -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() {

View file

@ -0,0 +1,92 @@
<!DOCTYPE html>
<html style="background: #fff">
<head>
<title>Updating Mailspring Database...</title>
<meta http-equiv="Content-Security-Policy" content="default-src * mailspring:; script-src 'self' 'unsafe-eval' chrome-extension://react-developer-tools; style-src * 'unsafe-inline' mailspring:; img-src * data: mailspring: file:;">
<style>
.progress {
position: relative;
height: 4px;
display: block;
width: 100%;
background-color: #ccc;
border-radius: 2px;
background-clip: padding-box;
margin: 0.5rem 0 1rem 0;
overflow: hidden; }
.progress .indeterminate {
background-color: #666; }
.progress .indeterminate:before {
content: '';
position: absolute;
background-color: inherit;
top: 0;
left: 0;
bottom: 0;
will-change: left, right;
-webkit-animation: indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;
animation: indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; }
.progress .indeterminate:after {
content: '';
position: absolute;
background-color: inherit;
top: 0;
left: 0;
bottom: 0;
will-change: left, right;
-webkit-animation: indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;
animation: indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;
-webkit-animation-delay: 1.15s;
animation-delay: 1.15s; }
@-webkit-keyframes indeterminate {
0% {
left: -35%;
right: 100%; }
60% {
left: 100%;
right: -90%; }
100% {
left: 100%;
right: -90%; } }
@keyframes indeterminate {
0% {
left: -35%;
right: 100%; }
60% {
left: 100%;
right: -90%; }
100% {
left: 100%;
right: -90%; } }
@-webkit-keyframes indeterminate-short {
0% {
left: -200%;
right: 100%; }
60% {
left: 107%;
right: -8%; }
100% {
left: 107%;
right: -8%; } }
@keyframes indeterminate-short {
0% {
left: -200%;
right: 100%; }
60% {
left: 107%;
right: -8%; }
100% {
left: 107%;
right: -8%; } }
</style>
</head>
<body style="padding-left: 1em; padding-right: 1em; background-color:#fcfcfc; font-family: sans-serif; font-size: 0.9em; color: #333; line-height: 1.3em;">
<div style="padding-top:10px; padding-bottom:7px; font-size:0.95em;">
Mailspring is upgrading your email database and will start momentarily...
</div>
<div class="progress">
<div class="indeterminate"></div>
</div>
</body>
</html>

92
app/static/db-vacuum.html Normal file
View file

@ -0,0 +1,92 @@
<!DOCTYPE html>
<html style="background: #fff">
<head>
<title>Preparing Mailspring...</title>
<meta http-equiv="Content-Security-Policy" content="default-src * mailspring:; script-src 'self' 'unsafe-eval' chrome-extension://react-developer-tools; style-src * 'unsafe-inline' mailspring:; img-src * data: mailspring: file:;">
<style>
.progress {
position: relative;
height: 4px;
display: block;
width: 100%;
background-color: #ccc;
border-radius: 2px;
background-clip: padding-box;
margin: 0.5rem 0 1rem 0;
overflow: hidden; }
.progress .indeterminate {
background-color: #666; }
.progress .indeterminate:before {
content: '';
position: absolute;
background-color: inherit;
top: 0;
left: 0;
bottom: 0;
will-change: left, right;
-webkit-animation: indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;
animation: indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; }
.progress .indeterminate:after {
content: '';
position: absolute;
background-color: inherit;
top: 0;
left: 0;
bottom: 0;
will-change: left, right;
-webkit-animation: indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;
animation: indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;
-webkit-animation-delay: 1.15s;
animation-delay: 1.15s; }
@-webkit-keyframes indeterminate {
0% {
left: -35%;
right: 100%; }
60% {
left: 100%;
right: -90%; }
100% {
left: 100%;
right: -90%; } }
@keyframes indeterminate {
0% {
left: -35%;
right: 100%; }
60% {
left: 100%;
right: -90%; }
100% {
left: 100%;
right: -90%; } }
@-webkit-keyframes indeterminate-short {
0% {
left: -200%;
right: 100%; }
60% {
left: 107%;
right: -8%; }
100% {
left: 107%;
right: -8%; } }
@keyframes indeterminate-short {
0% {
left: -200%;
right: 100%; }
60% {
left: 107%;
right: -8%; }
100% {
left: 107%;
right: -8%; } }
</style>
</head>
<body style="padding-left: 1em; padding-right: 1em; background-color:#fcfcfc; font-family: sans-serif; font-size: 0.9em; color: #333; line-height: 1.3em;">
<div style="padding-top:10px; padding-bottom:7px; font-size:0.95em;">
Mailspring is optimizing your email database to save space and will start momentarily...
</div>
<div class="progress">
<div class="indeterminate"></div>
</div>
</body>
</html>

@ -1 +1 @@
Subproject commit abed89b38711760f01b56dc3611024b32e12d229
Subproject commit f79cefcec98135e3fa27ff2c2e4f5f2e05a512bf