mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-09-22 16:26:08 +08:00
[client-sync] Refactor MessageProcessor to be more robust to errors
Summary: Errors in the MessageProcessor were causing sync to get stuck occasionally. This diff refactors queueMessageForProcessing and friends so that they're more robust to errors during promise construction. Test Plan: Run locally Reviewers: juan, spang, evan Reviewed By: evan Differential Revision: https://phab.nylas.com/D4190
This commit is contained in:
parent
c971ed03e2
commit
792994d95c
|
@ -47,14 +47,22 @@ class MessageProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns Promise that resolves when message has been processed
|
* @returns Promise that resolves when message has been processed. This
|
||||||
* This promise will never reject, given that this function is meant to be
|
* promise will never reject. If message processing fails, we will register
|
||||||
* called as a fire and forget operation
|
* the failure in the folder syncState.
|
||||||
* If message processing fails, we will register the failure in the folder
|
|
||||||
* syncState
|
|
||||||
*/
|
*/
|
||||||
queueMessageForProcessing({accountId, folderId, imapMessage, struct, desiredParts, throttle = true} = {}) {
|
queueMessageForProcessing({accountId, folderId, imapMessage, struct, desiredParts, throttle = true} = {}) {
|
||||||
return new Promise((resolve) => {
|
return new Promise(async (resolve) => {
|
||||||
|
let logger;
|
||||||
|
let folder;
|
||||||
|
try {
|
||||||
|
const accountDb = await LocalDatabaseConnector.forShared()
|
||||||
|
const account = await accountDb.Account.findById(accountId)
|
||||||
|
const db = await LocalDatabaseConnector.forAccount(accountId);
|
||||||
|
const {Folder} = db
|
||||||
|
folder = await Folder.findById(folderId)
|
||||||
|
logger = global.Logger.forAccount(account)
|
||||||
|
|
||||||
this._queueLength++
|
this._queueLength++
|
||||||
this._queue = this._queue.then(async () => {
|
this._queue = this._queue.then(async () => {
|
||||||
if (this._currentChunkSize === 0) {
|
if (this._currentChunkSize === 0) {
|
||||||
|
@ -62,7 +70,7 @@ class MessageProcessor {
|
||||||
}
|
}
|
||||||
this._currentChunkSize++;
|
this._currentChunkSize++;
|
||||||
|
|
||||||
await this._processMessage({accountId, folderId, imapMessage, struct, desiredParts})
|
await this._processMessage({db, accountId, folder, imapMessage, struct, desiredParts, logger})
|
||||||
this._queueLength--
|
this._queueLength--
|
||||||
|
|
||||||
// Throttle message processing to meter cpu usage
|
// Throttle message processing to meter cpu usage
|
||||||
|
@ -79,20 +87,21 @@ class MessageProcessor {
|
||||||
if (this._queueLength === 0) {
|
if (this._queueLength === 0) {
|
||||||
this._queue = Promise.resolve()
|
this._queue = Promise.resolve()
|
||||||
}
|
}
|
||||||
resolve()
|
});
|
||||||
})
|
} catch (err) {
|
||||||
|
if (logger && folder) {
|
||||||
|
await this._onError({imapMessage, desiredParts, folder, err, logger});
|
||||||
|
} else {
|
||||||
|
NylasEnv.reportError(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async _processMessage({accountId, folderId, imapMessage, struct, desiredParts}) {
|
async _processMessage({db, accountId, folder, imapMessage, struct, desiredParts, logger}) {
|
||||||
const db = await LocalDatabaseConnector.forAccount(accountId);
|
|
||||||
const {Message, Folder, Label} = db
|
|
||||||
const folder = await Folder.findById(folderId)
|
|
||||||
const accountDb = await LocalDatabaseConnector.forShared()
|
|
||||||
const account = await accountDb.Account.findById(accountId)
|
|
||||||
const logger = global.Logger.forAccount(account)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const {Message, Folder, Label} = db;
|
||||||
const messageValues = await MessageFactory.parseFromImap(imapMessage, desiredParts, {
|
const messageValues = await MessageFactory.parseFromImap(imapMessage, desiredParts, {
|
||||||
db,
|
db,
|
||||||
folder,
|
folder,
|
||||||
|
@ -147,6 +156,12 @@ class MessageProcessor {
|
||||||
logger.log(`🔃 ✉️ (${folder.name}) "${messageValues.subject}" - ${messageValues.date}`)
|
logger.log(`🔃 ✉️ (${folder.name}) "${messageValues.subject}" - ${messageValues.date}`)
|
||||||
return processedMessage
|
return processedMessage
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
await this._onError({imapMessage, desiredParts, folder, err, logger});
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async _onError({imapMessage, desiredParts, folder, err, logger}) {
|
||||||
logger.error(`MessageProcessor: Could not build message`, {
|
logger.error(`MessageProcessor: Could not build message`, {
|
||||||
err,
|
err,
|
||||||
imapMessage,
|
imapMessage,
|
||||||
|
@ -175,8 +190,6 @@ class MessageProcessor {
|
||||||
mkdirp.sync(outDir);
|
mkdirp.sync(outDir);
|
||||||
fs.writeFileSync(outFile, outJSON);
|
fs.writeFileSync(outFile, outJSON);
|
||||||
}
|
}
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replaces ["<rfc2822messageid>", ...] with [[object Reference], ...]
|
// Replaces ["<rfc2822messageid>", ...] with [[object Reference], ...]
|
||||||
|
|
Loading…
Reference in a new issue