Commit graph

346 commits

Author SHA1 Message Date
Juan Tejada
9a3470bacb [local-sync] 🎨 logger
If the first argument to our local-sync logger is an object
(this is bunyan's api, and it's how we log from isomorphic-core and cloud-* packages
in order to have structured json logs for logstash), make sure we log
the object last and the string that comes as the second argument first.
2017-02-08 18:27:09 -08:00
Christine Spang
2eeae66b2d [local-sync] Fix threading bug with open and link tracking enabled
Summary: Fixes T7649

Test Plan: FML writing unit tests now

Reviewers: evan, mark, juan

Reviewed By: mark, juan

Maniphest Tasks: T7649

Differential Revision: https://phab.nylas.com/D3863
2017-02-08 17:37:59 -08:00
Evan Morikawa
bf99b7862c [local-sync] use different port in dev mode
Summary:
This diff (and the K2 counterpart diff) allow us to run dev-mode Nylas
Mail side-by-side with prod Nylas Mail.

There were 4 things that needed to change:

1. Use different config dir
2. Use different keychain name
3. Use different localhost port
4. Prevent Electron's `app.makeSingleInstance` from killing our app

All of these are activated through `NylasEnv.inDevMode()`.

Test Plan: Manual

Reviewers: halla, mark, spang, khamidou, juan

Reviewed By: juan

Differential Revision: https://phab.nylas.com/D3861
2017-02-08 18:16:32 -05:00
Juan Tejada
c3873c16d6 [local-sync] Fix local-sync logs relayed to main (browser) process
Summary:
In electron, the --enable-logging flag makes it so the main browser
process logs to stdout all of the logs generated from within the renderer
processes.

Unfortunately, the main process will only log out the first argument passed to
`console.log` from within a renderer process (see https://github.com/electron/electron/issues/7061)

This commit makes it so that the local sync logger logs most of the log line in the first
argument passed to `console.log`

Test Plan: manual

Reviewers: evan, mark

Reviewed By: mark

Differential Revision: https://phab.nylas.com/D3852
2017-02-07 12:01:16 -08:00
Juan Tejada
a5d2a92a61 [local-sync] Fix SyncMetricsCollector logger 2017-02-07 11:19:31 -08:00
Juan Tejada
00552469b3 [local-sync] Log account info in all logs during local sync + color code
Summary:
When multiple accounts are syncing, it's very hard to scan the local
sync logs because it is unclear to which account the logs belong to,
and it makes debugging hard.

This commit makes it so that all logs from local-sync include the
account info, with the account email prefixed at the beginning of each
log line (this allows filtering), and color coded by account.

Test Plan: manual

Reviewers: mark, spang, khamidou, evan, halla

Reviewed By: evan, halla

Differential Revision: https://phab.nylas.com/D3851
2017-02-07 11:04:10 -08:00
Juan Tejada
ab95b9a612 [local-sync] Continously increment timeout for imap connection if we see timeout errors
Summary:
On each sync loop, we increment the socketTimeout based on how many times we've
seen socket timeouts in a row. The max socket timeout is 10m

Test Plan: manual

Reviewers: evan, spang, mark

Reviewed By: mark

Differential Revision: https://phab.nylas.com/D3843
2017-02-06 14:09:34 -08:00
Christine Spang
a22b3a1fc0 [local-sync] Download message batches newest first
Summary:
In most cases (and especially so on Gmail and in the inbox on generic
IMAP), messages with higher UIDs are newer---and even if they aren't the
newest possible messages in other generic IMAP folders, they are the
most recent messages that have been moved to that folder.

Our previous batching strategy unfortunately resulted in us downloading
the lowest UID in each batch first, which was especially confusing when
connecting a new account and having the first message pop up on the
screen be a message from hours or days ago.

This patch changes the batching strategy in three ways:

1. Within a batch, we process downloaded messages from highest UID to
lowest UID.

2. We download batches in order of the ones containing the highest UIDs
first.

3. We group together more UIDs within a single batch by ignoring charset
and transfer-encoding on parts and grouping only by MIME part IDs (which
is the only thing you have to pass to the IMAP FETCH command---no idea
why we included this extraneous part data before, probably just
convenience.)

Example old grouping:

  batch key: '[{"id":"2","transferEncoding":"QUOTED-PRINTABLE","charset":"UTF-8","mimeType":"text/html"}]'
  batch UIDs: [356416,356418,356420,356423,356432,356433,356435,356436,356437,356442,356444]

  batch key: '[{"id":"2","transferEncoding":"QUOTED-PRINTABLE","charset":"Windows-1252","mimeType":"text/html"}]'
  batch UIDs: [353777]

In the new strategy, all of these messages will be downloaded with the
same FETCH command, reducing IMAP round trips before message processing
begins.

Fixes T7770

Test Plan: manual - connect a new account and see that most recent message downloads first

Reviewers: mark, evan, juan

Reviewed By: juan

Maniphest Tasks: T7770

Differential Revision: https://phab.nylas.com/D3838
2017-02-06 10:30:02 -08:00
Juan Tejada
651cefb154 Fix local-sync logger 2017-02-06 09:11:22 -08:00
Halla Moore
51f34107d4 [local-sync] Remove isSending bit
Summary:
`isSending` was an artifact from the cloud sync engine that was used to
double check that the sending process for a multi-send draft had been
initiated. I don't believe the intermediate steps are API calls anymore,
and we've had the relevant code commented out for awhile. Time to kill it!

I've revived the double-sending tests in N1 to ensure we still have sufficient
checks against sending the draft again while the first call is still sending.
See D3834

Test Plan: N1 unit tests

Reviewers: juan, evan

Reviewed By: juan, evan

Differential Revision: https://phab.nylas.com/D3835
2017-02-03 14:21:32 -08:00
Juan Tejada
0c34238862 🎨 rm bad comment 2017-02-03 11:30:15 -08:00
Christine Spang
8b9f89ab14 [local-api] 🎨 Remove unused message and file GET routes
Summary:
This code is dead and has confused me grepping around the codebase before.

If for some unexpected reason we need these routes back in the future, we
can always extract them from version control. For now the routes we aren't
using are a distraction.

Test Plan: been using Nylas Mail with this local patch all week

Reviewers: evan, halla, juan

Reviewed By: juan

Differential Revision: https://phab.nylas.com/D3833
2017-02-03 10:42:22 -08:00
Juan Tejada
574f171fbd [local-sync] Properly set the sent label for Gmail accounts
Summary:
We can't try to set or remove the sent label on gmail accounts because
the operation will silently fail and cause the threads to later bounce
back.

This occurred when trying to delete or archive a thread that contained a
sent message, and we incorrectly tried to overwrite or remove all of the
labels on messages, without regard for sent.

This was causing https://github.com/nylas/nylas-mail/issues/2706 and
sending and archiving to immediately bounce back.

Addresses T7757

Test Plan: unit tests

Reviewers: halla, evan, spang

Reviewed By: halla, evan, spang

Differential Revision: https://phab.nylas.com/D3829
2017-02-02 17:20:38 -08:00
Juan Tejada
7b63912955 [local-sync] Correctly retry syncback tasks
Summary:
Previously, we attempted to immeditely retry syncback tasks when a
RetryableError was encountered. However, if the error was an
IMAPConnection error, we would keep retrying with a broken connection,
which would keep failing.

The correct way to retry is to wait for the next sync loop, since at the
beginning of each loop we ensure that we are correctly connected to
imap.

To achieve this this commit simply marks a failed task as NEW if it
encoutners a RetryableError and we haven't retried too many times. To
keep track of the number of retries, we save a new field in the `props`
field of the request.

Test Plan: manual

Reviewers: evan, halla, mark, spang

Reviewed By: spang

Subscribers: khamidou

Differential Revision: https://phab.nylas.com/D3831
2017-02-02 17:19:13 -08:00
Karim Hamidou
ae32666609 [cloud-api] Base infrastructure for running cloud workers
Summary:
I've decided to break my snooze patches in multiple parts to make it easier to review. This diff contains all the code related to running workers in the cloud. Cloud workers all inherit from the `Worker` class which defines a bunch of useful things like error handling.

What's left to do:
- spawn workers based on the plugin type
- add monitoring (I'm going to add a simple HTTP endpoint for that)
- writing a migration for the local sync db and the prod metadata db.

Test Plan: Tested manually.

Reviewers: halla, evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D3814
2017-02-02 16:14:59 -08:00
Juan Tejada
cb9faea6f0 [local-sync] Small restructuring of local-sync specs
Summary: Make them map the same directory structure of `src`

Test Plan: unit

Reviewers: evan, halla, spang

Reviewed By: halla, spang

Differential Revision: https://phab.nylas.com/D3826
2017-02-02 14:48:26 -08:00
Christine Spang
c6f371aa0f [local-sync] Serialize category sync progress to edgehill rather than syncState
Summary:
syncState on folders may contain arbitrarily long arrays of UIDs
(particularly, failedUIDs). If we serialize this JSON column to
edgehill.db, we can end up serializing very large objects when
persisting the local task queue. When the queue contains many tasks,
this can balloon the JSON blob to megabytes, causing the main window and
the worker window to become unresponsive.

The UI doesn't need to know about IMAP bookkeeping internals, so
serialize the sync progress instead of the sync state. This has the
advantages that (1) we don't need to worry about future keys added
to the syncState being large and (2) when we add Exchange support
we already have an abstraction for sync progress.

Test Plan: manual

Reviewers: juan, mark, halla

Reviewed By: halla

Differential Revision: https://phab.nylas.com/D3817
2017-02-01 07:15:33 -08:00
Evan Morikawa
efba50bd9f [local-sync] properly cleanup broken messages 2017-02-01 06:57:30 -08:00
Evan Morikawa
04ff46eb04 [local-sync] fix cleanup of sent messages 2017-02-01 06:24:03 -08:00
Evan Morikawa
47f1f440d7 [local-sync] fixed issue where single digit date would create dupes 2017-01-31 18:00:42 -08:00
Juan Tejada
4769d4d476 [local-sync] Save error when clearing tasks INPROGRESS 2017-01-31 15:59:56 -08:00
Juan Tejada
7029653c00 [local-sync] Retry syncback tasks that throw retryable errors
Summary:
This will prevent us from showing error messages to the user when we
can automatically recover from the error

Test Plan: manual-- throw error from syncback task, check expected results

Reviewers: evan, mark, spang

Reviewed By: spang

Differential Revision: https://phab.nylas.com/D3812
2017-01-31 10:54:18 -08:00
Juan Tejada
71959b44fb [local-sync] Account for additional IMAP retryable errors
Summary:
There are 2 types of IMAP errors that need to be treated as retryable. See code
comments as to why.

Test Plan: manual

Reviewers: khamidou, evan, spang

Reviewed By: spang

Differential Revision: https://phab.nylas.com/D3811
2017-01-31 10:53:43 -08:00
Juan Tejada
6aa5ad509a 🎨 remove outdated comments 2017-01-30 22:28:38 -08:00
Juan Tejada
9abcf7e8d8 [local-sync] Report permanent sync errors to sentry 2017-01-30 21:59:03 -08:00
Juan Tejada
469cbad22b [local-sync] Fix compilation of FetchNewMessagesInFolder operation
Summary: This was broken because babel could not compile the `super` keyword

Test Plan: manual

Reviewers: evan, mark, halla

Reviewed By: halla

Differential Revision: https://phab.nylas.com/D3804
2017-01-27 13:57:19 -08:00
Juan Tejada
b4973589f0 [local-sync] Sync new uid in sent folder when moving to msg to sent
Summary:
EnsureMessageInSentFolder also needs to sync the sent folder to fetch
the uid of the newly moved message (like `MoveThreadToFolder` does)

Test Plan: manual

Reviewers: halla, mark, evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D3803
2017-01-27 12:50:19 -08:00
Juan Tejada
e29fe2ee9b [local-sync] When fetching /new/ messages, make sure we have fetchedmax
Summary:
In `FetchNewMessagesInFolder`, sometimes we haven't synced anything in the folder
we are trying to fetch new messages in. Previously this would just throw
an error, now we properly check if we have a fetchedmax, and if not just
run a normal fetch.

Also, when the target folder box was already open, we were not fetching the /latest/ box status to check the latest uidnext value, so we would skip fetching new messages when in fact there were new messages to fetch

(This can happen for example when moving a sent message to the Sent
folder before we've started syncing the Sent folder)

Test Plan: manual

Reviewers: halla, mark, evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D3802
2017-01-27 12:49:18 -08:00
Juan Tejada
575ff4a73e [local-sync] Ensure messages always have a uid after syncback tasks
Summary:
Syncback tasks that move messages to a different folder used to leave
those messages without a uid because it was unknown at the moment, and
it would only be discovered later on in the sync loop.
This had the unwanted effect of not allowing you to perform more than 1
syncback action on the same thread back to back (e.g. undoing an archive, or
sending and archiving immediately)

This commit makes it so that `SetThreadFolderAndLabels` and
`MoveThreadToFolder` runs a new sync task to fetch the new uids for the
moved messages.

We do this via a new sync task, `FetchNewMessagesInFolder` which /only/
fetches new messages in a folder (no fetching old messages or attribute
updates). This is a first step to cleaning up the gigantic
`FetchMessagesInFolder` task into smaller parts-- but that will come in
a separate diff. For now we want to fix the immediate problem.

See D3788 and D3789 for more details

Test Plan:
manually move threads around, undo moving threads, reply on a thread
and immediately archive

Reviewers: khamidou, mark, spang, halla, evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D3798
2017-01-27 08:28:33 -08:00
Juan Tejada
4480fd89a2 [local-sync] Correctly check presence of messages when updating thread
Summary:
updateMessagesFromThread requires `messages` to be an array only when
recompute is falsy

Test Plan: manual

Reviewers: halla

Reviewed By: halla

Differential Revision: https://phab.nylas.com/D3797
2017-01-26 16:08:17 -08:00
Juan Tejada
651a199cb6 [local-sync] Correctly check uidvalitity when syncing and save when updated
Summary:
If there were any uidvalidity changes after we've completely synced a folder, we
would completely ignore them and not attempt to sync the folder.

Also, we weren't saving the latest uidvalidity from the box to the folder
syncState as soon as we recovered, we only saved it until after fetching
messages. This meant that if the operation was interrupted before updating
syncState.uidvalidity, we would always think that we were in a state of uid invalidity

Recovering from uidvalidity was also broken because we weren't resetting the
fetched ranges, and unnecessarily setting the folderId to null, which meant that
we would never restore the uids of messages we had already fetched.

Test Plan: manual

Reviewers: evan, khamidou, mark, halla

Reviewed By: mark

Differential Revision: https://phab.nylas.com/D3796
2017-01-26 16:05:18 -08:00
Juan Tejada
668be7463d [local-sync] Correctly close imap connections when downloading files
Summary: Addresses T7708

Test Plan: manual

Reviewers: evan, khamidou, mark, halla

Reviewed By: khamidou, mark, halla

Subscribers: halla

Differential Revision: https://phab.nylas.com/D3795
2017-01-26 15:27:56 -08:00
Juan Tejada
1d96c3f4da [local-sync] Ensure syncback actions have uids available before running
Summary:
Given that we perform syncback actions optimistically, i.e. we save the changes to the database before they are synced, some messages might not have an IMAP UID if they haven't been synced in the loop.

When we encounter messages without uid, we could just skip them, but this would mean that we end up moving only a subset of the messages we intended to move, or not move any at all, while thinking that we /did/ move everything, which might cause the thread to bounceback later on when we sync the messages that were missing.

The permanent fix is for syncback actions to not succeed until their changes have been synced, which is coming up in a separate diff

Test Plan: manual

Reviewers: evan, spang, khamidou, mark

Reviewed By: mark

Subscribers: mark

Differential Revision: https://phab.nylas.com/D3789
2017-01-26 13:31:53 -08:00
Juan Tejada
f98b9449bf [local-sync] Fix transaction syntax 2017-01-26 09:19:17 -08:00
Juan Tejada
2391f58dfc Add comment 2017-01-26 00:06:20 -08:00
Juan Tejada
073310f49f [local-sync] Make sure folder move syncback actions clear folderImapUID 2017-01-26 00:06:20 -08:00
Christine Spang
6ddabff389 [local-sync] Avoid skipping All Mail updates if no new messages during Gmail inbox sync
Summary:
In JavaScript, null <= null is truthy. So if you set fetchedmax but not
fetchedmin and minUID, and then highestmodseq doesn't increment, we will
incorrectly skip updates on All Mail after the first batch of Gmail
inbox UID downloads, only making further progress on sync if the user
receives a new mail.

This patch tightens isSyncComplete() to require that all variables used
in the math comparisons are set.

Test Plan: manual 😢

Reviewers: evan, juan

Reviewed By: juan

Differential Revision: https://phab.nylas.com/D3787
2017-01-25 16:31:20 -08:00
Mark Hahnenberg
7ad9e36cec [local-sync] Set isBatteryCharging on startup
Summary:
Previously we just assumed that we were in the "charging" state and wouldn't
update that until the state changed. This would cause us to throttle even if
the app was opened while plugged in. Now we don't do that.

Test Plan: Run locally, verify that we no longer throttle

Reviewers: spang, evan, juan

Reviewed By: juan

Differential Revision: https://phab.nylas.com/D3782
2017-01-25 14:03:29 -08:00
Juan Tejada
c097a86169 [local-sync] Fix isDraft check (check array exists)
Summary: see title

Test Plan: manual

Reviewers: spang

Reviewed By: spang

Differential Revision: https://phab.nylas.com/D3781
2017-01-25 13:53:03 -08:00
Juan Tejada
b33c55443b [local-sync] Fix attribute updates
Summary:
Previously, when updating message attributes during folder sync, we
would fetch local db messages only by folderImapUID. This was incorrect,
because messages in different folders could have the same uid, so our
query would return messages from other folders, causing us to
incorrectly update their attributes.

This commit ensures we fetch local messages in the current folder

Test Plan: manual

Reviewers: evan, halla, mark, spang

Reviewed By: spang

Differential Revision: https://phab.nylas.com/D3777
2017-01-25 12:25:34 -08:00
Juan Tejada
470a47abfe [local-sync] Make sure thread is saved before updating folders/labels
We now correctly `await` for the `setFolders` and `setLabels`
operations, and make sure that the thread is always saved.

Apparently the `thread.id` check wasn't working as expected and we were skipping a
thread save, which only became apparent when we awaited for `setFolders`
and `setLabels`. Now, we always save the thread (like we did before this
method got updated)
2017-01-25 10:50:10 -08:00
Christine Spang
3f61e3da6a [local-sync] Sync isDraft correctly on Gmail
Summary:
When I tested if we could use labels in place of the flag, I had the
Drafts folder selected, not All Mail, and the label did not show up.
Turns out that if you have All Mail selected, all draft messages will be
correctly tagged with the Draft label.

With this patch, we should correctly sync isDraft on all supported
providers and suppress these messages from the app until if or when we
decide to implement draft sync.

Thanks Brandon Long from the Gmail team for the help in getting this right.

Test Plan: manual

Reviewers: juan, evan

Reviewed By: juan, evan

Differential Revision: https://phab.nylas.com/D3775
2017-01-25 10:36:46 -08:00
Juan Tejada
cdf43ba804 [local-sync] Outbox shouldn't be included in localized names for sent
Summary:
Otherwise accounts with `Sent` and an `Outbox` will both get the `sent`
role, causing inconsistencies in sync

Addresses T7682

Test Plan: manual

Reviewers: khamidou, spang

Reviewed By: khamidou, spang

Differential Revision: https://phab.nylas.com/D3773
2017-01-25 09:59:36 -08:00
Christine Spang
bc0b411be7 [local-sync] Remove duplicate db calls for looking up existing messages
Summary:
Now that message processing is serialized, this is unnecessary. I
was debugging something else and watched the code step through the
exact same db query twice in a row.

Test Plan: manual

Reviewers: evan, juan

Reviewed By: juan

Differential Revision: https://phab.nylas.com/D3764
2017-01-25 09:53:48 -08:00
Christine Spang
fba9ac0147 [local-sync] Still sync new mail during Gmail inbox UID prioritization
Summary: Fixes T7620

Test Plan: manual

Reviewers: mark, juan

Reviewed By: juan

Maniphest Tasks: T7620

Differential Revision: https://phab.nylas.com/D3765
2017-01-25 09:49:16 -08:00
Evan Morikawa
ddcd097c9b [local-sync] remove /account API endpoint
Summary:
It turns out we don't ever use the /account API endpoint.

The GET /accounts endpoint was designed to query all accounts connected to
a system for old K2, but we don't use that anymore. The environment
variable protecting the endpoint isn't set anywhere.

We used to `GET /account` from the N1 AccountStore to attempt to refresh
the health of the accounts. The accompianing diff to this one makes that
obsolete. We never need to query for the account health since the sync
loop pushes it to us through `Actions.updateAccount`.

We also never `DELETE /account` because our local-sync runs a function
called `ensureK2Consistency` that compares its DB against the Nylas Mail
`AccountStore`.

This file has always been a huge source of confusion to me and a massive
red herring for anyone trying to understand how the account system work.
The accompyaning diff has more comments explaining the existing system

Depends on https://phab.nylas.com/D3770

Test Plan:
Manually boot N1. Ensure existing account works. Add a new account. Remove
an account. Open the developer tools and check that all the tabs still
work.

Lots of grepping through the code base.

Reviewers: halla, mark, juan, khamidou

Reviewed By: juan, khamidou

Differential Revision: https://phab.nylas.com/D3769
2017-01-25 10:10:10 -05:00
Juan Tejada
0b89947c13 [local-sync] Make EnsureMessageInSentFolder save db changes after imap success
Summary:
This will solve T7579 when saving messages to the sent folder. I
attempted to clean up the references code but decided it was better left for a
new diff, so added a bunch of TODO's in this diff

Test Plan: manual

Reviewers: halla, spang, evan

Reviewed By: spang, evan

Differential Revision: https://phab.nylas.com/D3766
2017-01-25 00:29:30 -08:00
Juan Tejada
8b3944d235 [local-sync] Make category syncback tasks save changes after imap success
Summary: This will solve T7579 for actions involving categories (folders/labels)

Test Plan: manual

Reviewers: khamidou, halla, mark, evan, spang

Reviewed By: evan, spang

Differential Revision: https://phab.nylas.com/D3753
2017-01-24 07:30:43 -08:00
Juan Tejada
e909c8dfc7 [local-sync] Make thread syncback tasks save changes after imap success
Summary: This will solve T7579 for thread operations

Test Plan: manual

Reviewers: evan, mark, khamidou, halla, spang

Reviewed By: halla, spang

Differential Revision: https://phab.nylas.com/D3755
2017-01-24 07:29:25 -08:00
Christine Spang
359e32282f [local-sync] Sync draft flag from provider to K2 & exclude drafts from Edgehill
Summary:
We've been syncing drafts messages but not the drafts flag in K2, making
them appear in Edgehill as regular old messages.

This commit makes K2 sync the drafts flag, and also correctly label
folders called "Drafts" with the 'drafts' role.

Because 2-way syncing of drafts is very complex and error-prone since
you need to add new drafts and delete the old ones on every update, and
we reaally don't want to do things like create multiplying draft copies
or accidentally lose a draft someone started composing elsewhere, we
simply exclude messages marked as drafts from being serialized to
Edgehill through the delta stream for now. This removes the confusing
behaviour and also sets a better stage for completing drafts sync later.

Eventually we will also want to add functionality to allow users to
select their drafts folder, but for now this code does the right thing
in many more cases.

While investigating this behaviour, I also discovered a bug we've never
seen before where Gmail isn't applying the \Draft flag to draft
messages, no matter which folder we fetch them from. :-/ This is very
unfortunate and there's no way for us to work around it other than to
fetch messages in the Drafts folder and manually apply the flag locally,
since "drafts" is not a label in Gmail, only another IMAP folder. Brandon
Long from the Gmail team says that this is because they've had
problems with clients which sync drafts, so the Gmail web client and
mobile apps do not set the \Draft flag on drafts. (I don't get how this
solves their problem, but okay.) Let's solve the issue on Gmail if it
comes up by user demand—should be relatively straightforward to
implement, but it adds sync work & complexity.

Fixes T7593

Test Plan: manual

Reviewers: halla, juan

Reviewed By: juan

Maniphest Tasks: T7593

Differential Revision: https://phab.nylas.com/D3749
2017-01-23 20:58:32 -08:00