[local-sync] Report folder syncState to N1

Summary:
Associated N1 diff: D3515

Stop ignoring deltas for Folder.syncState updates

Test Plan: Manual

Reviewers: mark, evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D3514
This commit is contained in:
Juan Tejada 2016-12-15 11:06:34 -08:00
parent e5a9e2cc9e
commit b6d8459d50
6 changed files with 51 additions and 12 deletions

View file

@ -24,7 +24,8 @@ module.exports = {
get() {
const val = this.getDataValue(fieldName);
if (!val) {
return [];
const {defaultValue} = options
return defaultValue || [];
}
const arr = JSON.parse(val)
if (!Array.isArray(arr)) {

View file

@ -9,7 +9,7 @@ module.exports = (db, sequelize, {only, onCreatedTransaction} = {}) => {
}
const allIgnoredFields = (changedFields) => {
return _.isEqual(changedFields, ['syncState', 'updatedAt', 'version']) || _.isEqual(changedFields, ['syncState']);
return _.isEqual(changedFields, ['updatedAt', 'version'])
}
const transactionLogger = (event) => {
@ -24,7 +24,7 @@ module.exports = (db, sequelize, {only, onCreatedTransaction} = {}) => {
}
const changedFields = Object.keys(_changed)
if ((isTransaction($modelOptions) || allIgnoredFields(changedFields))) {
if ((isTransaction($modelOptions) || changedFields.length === 0 || allIgnoredFields(changedFields))) {
return;
}

View file

@ -5,8 +5,9 @@ const BASE_ROLES = ['inbox', 'sent', 'trash', 'spam'];
const GMAIL_ROLES_WITH_FOLDERS = ['all', 'trash', 'spam'];
class FetchFolderList {
constructor(provider, logger) {
this._provider = provider;
constructor(account, logger) {
this._account = account;
this._provider = account.provider;
this._logger = logger;
if (!this._logger) {
throw new Error("FetchFolderList requires a logger")
@ -154,10 +155,12 @@ class FetchFolderList {
}
})
let promises = [Promise.resolve()]
promises = promises.concat(created.map(cat => cat.save({transaction})))
promises = promises.concat(deleted.map(cat => cat.destroy({transaction})))
return Promise.all(promises)
await Promise.all([].concat(
created.map(cat => cat.save({transaction})),
deleted.map(cat => cat.destroy({transaction}))
))
return Promise.resolve()
});
}
}

View file

@ -306,7 +306,7 @@ class FetchMessagesInFolder {
async _fetchUnsyncedMessages() {
const savedSyncState = this._folder.syncState;
const isFirstSync = savedSyncState.fetchedmax === undefined;
const isFirstSync = savedSyncState.fetchedmax == null;
const boxUidnext = this._box.uidnext;
const boxUidvalidity = this._box.uidvalidity;
@ -443,6 +443,17 @@ class FetchMessagesInFolder {
this._imap = imap;
this._box = await this._openMailboxAndEnsureValidity();
// If we haven't set any syncState at all, let's set it for the first time
// to generate a delta for N1
if (_.isEmpty(this._folder.syncState)) {
await this.updateFolderSyncState({
uidnext: this._box.uidnext,
uidvalidity: this._box.uidvalidity,
fetchedmin: null,
fetchedmax: null,
})
}
await this._fetchUnsyncedMessages()
await this._runScan()
}

View file

@ -235,7 +235,7 @@ class SyncWorker {
await this._account.update({syncError: null});
await this.ensureConnection();
await this.runNewSyncbackRequests();
await this._conn.runOperation(new FetchFolderList(this._account.provider, this._logger));
await this._conn.runOperation(new FetchFolderList(this._account, this._logger));
await this.syncMessagesInAllFolders();
await this.cleanupOrpahnMessages();
await this.onSyncDidComplete();

View file

@ -9,7 +9,30 @@ module.exports = (sequelize, Sequelize) => {
version: Sequelize.INTEGER,
name: Sequelize.STRING,
role: Sequelize.STRING,
syncState: JSONColumn('syncState', {defaultValue: {}}),
/**
* Sync state has the following shape, and it indicates how much of the
* folder we've synced and what's next for syncing:
*
* {
* // Lowest (oldest) IMAP uid we've fetched in folder
* fetchedmin,
*
* // Highest (newest) IMAP uid we've fetched in folder
* fetchedmax,
*
* // Highest (most recent) uid in the folder. If this changes, it means
* // there is new mail we haven't synced
* uidnext,
*
* // Flag provided by IMAP server to indicate if we need to indicate if
* // we need resync whole folder
* uidvalidity,
*
* // Timestamp when we last fetched unseen messages
* timeFetchedUnseen,
* }
*/
syncState: JSONColumn('syncState'),
}, {
indexes: [
{
@ -39,6 +62,7 @@ module.exports = (sequelize, Sequelize) => {
object: 'folder',
name: this.role,
display_name: formatImapPath(this.name),
sync_state: this.syncState,
};
},
},