mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-09-12 23:54:45 +08:00
[client-sync] Use IMAPConnectionPool for downloading files
Summary: See title Test Plan: Run locally, verify downloading files works Reviewers: evan, spang, juan Reviewed By: juan Differential Revision: https://phab.nylas.com/D4004
This commit is contained in:
parent
44f5cc580b
commit
c4ccd8aac4
1 changed files with 32 additions and 33 deletions
|
@ -1,6 +1,7 @@
|
||||||
const base64 = require('base64-stream');
|
const base64 = require('base64-stream');
|
||||||
const {IMAPConnection} = require('isomorphic-core')
|
const {IMAPConnectionPool} = require('isomorphic-core')
|
||||||
const {QuotedPrintableStreamDecoder} = require('../shared/stream-decoders')
|
const {QuotedPrintableStreamDecoder} = require('../shared/stream-decoders')
|
||||||
|
const {Actions} = require('nylas-exports')
|
||||||
|
|
||||||
module.exports = (sequelize, Sequelize) => {
|
module.exports = (sequelize, Sequelize) => {
|
||||||
return sequelize.define('file', {
|
return sequelize.define('file', {
|
||||||
|
@ -26,20 +27,14 @@ module.exports = (sequelize, Sequelize) => {
|
||||||
},
|
},
|
||||||
instanceMethods: {
|
instanceMethods: {
|
||||||
async fetch({account, db, logger}) {
|
async fetch({account, db, logger}) {
|
||||||
let numAttempts = 0;
|
const message = await this.getMessage()
|
||||||
const maxAttempts = 5;
|
const folder = await message.getFolder()
|
||||||
let currentTimeout = 30 * 1000;
|
let numTimeoutErrors = 0;
|
||||||
const maxTimeout = 2 * 60 * 1000;
|
let result = null;
|
||||||
while (numAttempts <= maxAttempts) {
|
await IMAPConnectionPool.withConnectionsForAccount(account, {
|
||||||
const settings = Object.assign({},
|
desiredCount: 1,
|
||||||
account.connectionSettings,
|
logger,
|
||||||
account.decryptedCredentials(),
|
onConnected: async ([connection], done) => {
|
||||||
{socketTimeout: currentTimeout})
|
|
||||||
const message = await this.getMessage()
|
|
||||||
let connection = null;
|
|
||||||
try {
|
|
||||||
connection = await IMAPConnection.connect({db, settings, logger})
|
|
||||||
const folder = await message.getFolder()
|
|
||||||
const imapBox = await connection.openBox(folder.name)
|
const imapBox = await connection.openBox(folder.name)
|
||||||
const stream = await imapBox.fetchMessageStream(message.folderImapUID, {
|
const stream = await imapBox.fetchMessageStream(message.folderImapUID, {
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
|
@ -47,16 +42,20 @@ module.exports = (sequelize, Sequelize) => {
|
||||||
struct: true,
|
struct: true,
|
||||||
},
|
},
|
||||||
onFetchComplete() {
|
onFetchComplete() {
|
||||||
connection.end()
|
done();
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
throw new Error(`Unable to fetch binary data for File ${this.id}`)
|
throw new Error(`Unable to fetch binary data for File ${this.id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (/quoted-printable/i.test(this.encoding)) {
|
if (/quoted-printable/i.test(this.encoding)) {
|
||||||
return stream.pipe(new QuotedPrintableStreamDecoder({charset: this.charset}))
|
result = stream.pipe(new QuotedPrintableStreamDecoder({charset: this.charset}));
|
||||||
|
return true;
|
||||||
} else if (/base64/i.test(this.encoding)) {
|
} else if (/base64/i.test(this.encoding)) {
|
||||||
return stream.pipe(base64.decode());
|
result = stream.pipe(base64.decode());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is no encoding, or the encoding is something like
|
// If there is no encoding, or the encoding is something like
|
||||||
|
@ -64,20 +63,20 @@ module.exports = (sequelize, Sequelize) => {
|
||||||
// stream will be written directly to disk. It's then up to the
|
// stream will be written directly to disk. It's then up to the
|
||||||
// user's computer to decide how to interpret the bytes we've
|
// user's computer to decide how to interpret the bytes we've
|
||||||
// dumped to disk.
|
// dumped to disk.
|
||||||
return stream
|
result = stream;
|
||||||
} catch (err) {
|
return true;
|
||||||
if (connection) {
|
},
|
||||||
connection.end();
|
onTimeout: (socketTimeout) => {
|
||||||
}
|
numTimeoutErrors += 1;
|
||||||
if (numAttempts <= maxAttempts) {
|
Actions.recordUserEvent('Timeout error downloading file', {
|
||||||
console.error('Error trying to fetch file:', err);
|
accountId: account.id,
|
||||||
numAttempts += 1;
|
provider: account.provider,
|
||||||
currentTimeout = Math.min(maxTimeout, currentTimeout * 2);
|
socketTimeout,
|
||||||
continue;
|
numTimeoutErrors,
|
||||||
}
|
});
|
||||||
throw err
|
},
|
||||||
}
|
});
|
||||||
}
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
toJSON() {
|
toJSON() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue