Commit graph

102 commits

Author SHA1 Message Date
Christine Spang b1aeefe433 fix(sync-worker): Don't call _determineWorkerPool() twice
A race condition on bootup was causing us to sometimes start
two delta sync workers for the same account.
2016-12-22 12:43:45 -08:00
Evan Morikawa 083021d860 perf(delta): replaces API delta stream with direct in-memory one
Summary:
This replaces the API delta stream with a direct in-memory one

Depends on D3548

Test Plan: manual

Reviewers: halla, jackie

Reviewed By: halla, jackie

Subscribers: juan

Differential Revision: https://phab.nylas.com/D3549
2016-12-21 18:44:17 -08:00
Halla Moore 9066078911 fix(delta-processor): Return created models in the expected format
Summary:
We were returning an array of arrays, when really we wanted an object
of arrays keyed by model type. This also involved removing an implementation
of mapObject that was overwriting underscore's implementation of it.

Test Plan: local, having others try it.

Reviewers: juan

Reviewed By: juan

Differential Revision: https://phab.nylas.com/D3509
2016-12-15 12:12:37 -08:00
Juan Tejada 9039c49dba fix(send/tasks): Fix deltas for SyncbackRequest SyncbackTaskAPIRequest
Summary:
This commit fixes processing deltas for `ProviderSyncbackRequests` and
resolution of the `SyncbackTaskAPIRequest`

Specifically:
- Fix and update field definitions for `ProviderSyncbackRequest`
- Correctly parse the error attached to any `ProviderSyncbackRequest`
- Correctly process deltas for `ProviderSyncbackRequests` inside the
delta-processor
- Fix any tasks that used `SyncbackTaskAPIRequest`, and update send to use those

Depends on D3510

Test Plan: Todo/Manual

Reviewers: jackie, halla, evan

Reviewed By: halla, evan

Differential Revision: https://phab.nylas.com/D3511
2016-12-15 11:57:14 -08:00
Juan Tejada d92506d8f1 fix(sync-status): Change old per model status, in favor of per folder
Summary:
Addresses T7275
Previously, we kept track of the sync status of each API model, and the progress
we'd made syncing all available models (e.g. all threads, messages, events, etc)

Given K2's set up, we are now keeping track of sync status per folder, i.e. what
percent of the folder's messages we've synced. This status is now reported from K2
to N1 via folder object deltas, and this commit rewrites the
NylasSyncStatusStore (in ES6) to reflect that.

The new Store keeps the sync state per account, which is the merged state of
per folder sync state, and delta connections state.
We also got rid of `CategoryStore.whenCategoriesReady` in favor of
`whenCategoryListSynced`, which is derived from the fact hat as long as we've
started syncing one folder, we've already synced the entire list of of folders/labels.

There are a couple of TODOs to be addressed in upcoming diffs:
- T7329 Restore the sidebar component to show sync progress, which was previously removed
- T7330 Figure out how to report sync progress per label, specifically, we are interested in knowing how much of the inbox we've synced, which is a label in Gmail. (This might be a non-issue if we sync the inbox very fast, first)

Depends on D3514

Test Plan: Manual

Reviewers: mark, evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D3515
2016-12-15 11:17:20 -08:00
Evan Morikawa d1c587a01c fix(spec): add support for async specs and disable misbehaving ones
More spec fixes

replace process.nextTick with setTimeout(fn, 0) for specs

Also added an unspy in the afterEach

Temporarily disable specs

fix(spec): start fixing specs

Summary:
This is the WIP fix to our spec runner.

Several tests have been completely commented out that will require
substantially more work to fix. These have been added to our sprint
backlog.

Other tests have been fixed to update to new APIs or to deal with genuine
bugs that were introduced without our knowing!

The most common non-trivial change relates to observing the `NylasAPI` and
`NylasAPIRequest`. We used to observe the arguments to `makeRequest`.
Unfortunately `NylasAPIRequest.run` is argumentless. Instead you can do:
`NylasAPIRequest.prototype.run.mostRecentCall.object.options` to get the
`options` passed into the object. the `.object` property grabs the context
of the spy when it was last called.

Fixing these tests uncovered several concerning issues with our test
runner. I spent a while tracking down why our participant-text-field-spec
was failling every so often. I chose that spec because it was the first
spec to likely fail, thereby requiring looking at the least number of
preceding files. I tried binary searching, turning on and off, several
files beforehand only to realize that the failure rate was not determined
by a particular preceding test, but rather the existing and quantity of
preceding tests, AND the number of console.log statements I had. There is
some processor-dependent race condition going on that needs further
investigation.

I also discovered an issue with the file-download-spec. We were getting
errors about it accessing a file, which was very suspicious given the code
stubs out all fs access. This was caused due to a spec that called an
async function outside ot a `waitsForPromise` block or a `waitsFor` block.
The test completed, the spies were cleaned up, but the downstream async
chain was still running. By the time the async chain finished the runner
was already working on the next spec and the spies had been restored
(causing the real fs access to run).

Juan had an idea to kill the specs once one fails to prevent cascading
failures. I'll implement this in the next diff update

Test Plan: npm test

Reviewers: juan, halla, jackie

Differential Revision: https://phab.nylas.com/D3501

Disable other specs

Disable more broken specs

All specs turned off till passing state

Use async-safe versions of spec functions

Add async test spec

Remove unused package code

Remove canary spec
2016-12-15 13:02:00 -05:00
Juan Tejada 68e596bdf4 [local-sync] Correctly sync folders and labels
This commit will correctly keep track of folder and label ids when
creating them from N1.

Previously, when we sent the request to create a folder or label to our api,
we would immediately get back a serverId because it was created optimistically
in the back end— given that K2 is strictly non-optimistic, we won’t have a serverId
until some undetermined time in the future, and we need to somehow reference
the object that /was/ optimistically created in N1 to update the ui when
we do get the server id.

Since we can deterministically generate ids for folders and labels,
we "guess" what its going to be, and include it in the props of the syncback request
returned to N1. This is the simplest solution to get thing working
correctly right now, but we’ll need to revisit this in the future for
other types of objects (drafts, contacts, events), and revisit how we
will manage optimistic updates in N1 when we merge the 2 codebases
with K2 (given that K2 was designed to be non-optimisitc).
2016-12-05 18:57:13 -08:00
Ben Gotow b0b231094d fix(deltas): Minor tweaks to metadata delta processing 2016-12-05 10:19:37 -08:00
Ben Gotow a9ccd7370c fix(deltas): Minor adjustments for thread deltas 2016-12-02 15:59:05 -08:00
Jackie Luo ad5a1a6316 refactor(nylas-api): Make requests with helpers 2016-12-02 15:51:38 -08:00
Ben Gotow 0e8829b929 fix linter errors 2016-12-02 15:44:52 -08:00
Christine Spang a1a85e04be feat(metadata): Look up local thread IDs via message table when setting metadata
Since message IDs are now static but there's no good way to generate
static thread IDs while syncing an account from newest message first,
we give threads the ID of any message on that thread and, when setting
metadata, look up the local thread ID by first going through the
message table.
2016-12-02 14:13:58 -08:00
Evan Morikawa cee7d05017 debug(delta): add logs 2016-12-02 15:11:48 -05:00
Evan Morikawa cfc605136b refactor(sync): sync workers only use delta syncs now 2016-12-02 14:48:56 -05:00
Ben Gotow fb13abe8f4 fix(deltas): Process all deltas of each class in a single pass
Also changed the DeltaProcessor so it doesn’t query for models before sending out `Actions.didPassivelyReceiveCreateDeltas`, and renames it to be more clear it’s about deltas.
2016-12-02 11:41:49 -08:00
Ben Gotow e3b4fc859e fix(deltas): Remove extra params passed to streaming endpoint 2016-12-01 18:42:13 -08:00
Evan Morikawa 77799519e4 fix(spec): fixed specs for nylas-sync-worker 2016-12-01 14:00:20 -05:00
Evan Morikawa 278a4d16d4 fix(spec): progress on spec fixes for sync worker 2016-12-01 13:17:55 -05:00
Juan Tejada d409a5a3f9 fix(delats): Warn when receiving unkown obejct class 2016-12-01 09:14:02 -08:00
Evan Morikawa 380f370e7d fix(sync): Support N1Cloud auth errors. Fix LongConnection cleanup 2016-12-01 12:04:37 -05:00
Evan Morikawa 58874e8ad3 fix(delta): JSON blob persist failed to save properly 2016-12-01 11:04:19 -05:00
Ben Gotow ed74e454d2 fix(deltas): Fix deltaProcessor handling deletes wrong 2016-11-30 17:00:11 -08:00
Ben Gotow daed7146b5 fix(deltas): Delta.id is now a transaction id, need objectId 2016-11-30 16:53:52 -08:00
Juan Tejada dfee7ea9b6 fix(k2) fix local sync deltas 2016-11-30 16:13:26 -08:00
Evan Morikawa 3a72987f4d fix(delta): default cursor to 0 if no transactions exist yet 2016-11-30 17:56:59 -05:00
Evan Morikawa 3d4035ac64 fix(delta): fix issues with delta sync 2016-11-30 17:55:45 -05:00
Evan Morikawa 5582782ddd refactor(delta): add a second delta stream, convert to es6, and cleanup
This reverts commit ee5609bdb0.

Updates to nylas sync worker to support multiple cursors

Convert NylasSyncWorker to es6

Convert NylasSyncWorkerPool to es6

Extract into deltaProcessor

Update names to NylasSyncWorker state

Working on spec fixes

More spec fixes

Delta stream refactor fixes
2016-11-30 13:42:10 -05:00
Jackie Luo 7b7fbb3b1b refactor(nylas-api): Create API requests from tasks 2016-11-29 16:33:44 -08:00
Ben Gotow 848feaad60 fix(sync-worker): Missing binding arrow… 2016-11-29 12:44:02 -08:00
Juan Tejada 0b5f2841d5 fix(deltas) Update syncworker signature 2016-11-29 12:39:36 -08:00
Evan Morikawa ee5609bdb0 Rename DeltaStreamingConnection -> LocalDeltaSyncConnection 2016-11-28 17:13:18 -08:00
Evan Morikawa caba64d39d Update nylas-sync-worker to better fetch metadata 2016-11-28 16:59:04 -08:00
Evan Morikawa 9cbc284ed5 Fetch folders and labels at the same time 2016-11-28 16:11:10 -08:00
Ben Gotow 864766d463 fix(sync): Throttle instead of debounce for better initial sync 2016-11-28 12:05:41 -08:00
Halla Moore f4357ce166 change(API) Prevent N1 from sending "view" parameters in some API requests
- Threads: N1 always asks for the 'expanded' view, so K2 just always returns
the expanded view. N1 no longer needs to specify this.
- Messages: N1 only needed a 'count' view to display the initial sync progress
We've removed this progress bar and the corresponding request.
2016-11-21 15:16:04 -08:00
Ben Gotow 80b315d708 deps(*): Lift deps out of packages for simpler install / better deduping 2016-11-09 14:24:10 -08:00
Mark Hahnenberg dde4738363 Fix broken test
Summary:
Fixes a test that was broken due to my unfamiliarity with
CoffeeScript :-/

Test Plan: Tests

Reviewers: bengotow

Reviewed By: bengotow

Subscribers: juan

Differential Revision: https://phab.nylas.com/D3302
2016-09-26 16:49:22 -07:00
Mark Hahnenberg 0319528988 Add jitter to BackoffTimer
Summary:
This should help us avoid the thundering herd problem if we have some
kind of API outage affecting a wide number of clients.

Test Plan: Tests

Reviewers: bengotow

Reviewed By: bengotow

Subscribers: juan

Differential Revision: https://phab.nylas.com/D3297
2016-09-26 13:36:49 -07:00
Juan Tejada 3dccb374b3 fix(search/long-conn): Process results buffer before ending connection (#750)
NylasLongConnection ends the connection when the 'end' event is emitted
by the `request` object. When this happens, the global connection buffer is cleared.
Also, the global buffer holds the data we've received from the connection, and
whenever we receive new data, we accumulate it in the buffer and call a processBuffer function
which is throttled to 400ms.

Given that the buffer is global state, and processing occurs
asynchronously with a delay of up to 400ms, if the 'end' event on the connection is
fired before we actually get to process the buffer, we would clear it and show no results.

This scenario currently only affected search because if we accidentally
threw away some data when streaming deltas, we will get that data again
when we reopen the delta streaming connection.
2016-09-22 12:08:59 -07:00
Juan Tejada 7dadf2ccd3 fix(specs): Properly spy on streaming connection
- Prevent error logs and actually trying to start delta streaming
connections
2016-07-28 12:40:31 -07:00
Juan Tejada fb18299bc2 fix(log): Rm unecessary console.log call 2016-07-28 10:31:48 -07:00
Juan Tejada 4427f5eda1 fix(deltas): Update latest cursor, address comments
- Add test to make sure that latest cursor is updated
2016-07-27 14:30:12 -07:00
Juan Tejada aaeda2e5ac fix(deltas): Consolidate nylas-long-connection code
- Completely remove nylas-long-connection.coffee file and consolidate all logic into
nylas-long-connection.es6 and worker-sync/delta-streaming-connection.es6:
  - Separate it into DeltaStreamingConnection which is specific to the worker-sync
    package for handling deltas
  - NylasLongConnection is a "reusable" persistent connection to our API
    which is also used by the search package
  - This is a basically a fixed revision of https://phab.nylas.com/D2875,
    see difff for more info
- Makes it so delta streaming does not retry so aggressively on 403s, which
  happens whenever a user’s trial has expired
2016-07-27 02:56:55 -07:00
Ben Gotow 3f6415c119 fix(specs): Misc fixes 2016-07-20 12:33:52 -07:00
Evan Morikawa 27bfd91e32 fix(delta): add N1 token to delta stream connection 2016-07-13 22:02:48 -07:00
Carson Ip a3874ce1de Fix incorrect port number when using https (#2600)
When APIRoot is using https, the port will forced to be 443 even when APIRoot
indicates another port. This is because of the line options.port = 443
overwriting the correct options.port extracted by url.parse. This is fixed by
removing the problematic line. The default port is still 443 if you look into
https.js. In case we want a different default port in the future, we can do
options.port = options.port || 443.
2016-07-12 12:03:13 -07:00
Evan Morikawa c4753197ee fix(analytics): improved analytics 2016-06-07 13:38:47 -07:00
Ben Gotow 508c92f599 fix(sync): Always restart where left off after initial sync interrupted 2016-06-02 18:56:09 -07:00
Ben Gotow 0c77f61838 fix(config): removeAtKeyPath => undo, guard with assertions 2016-05-25 14:03:09 -07:00
Ben Gotow 345d006533 fix(connection): account.id => accountId 2016-05-16 03:26:23 -05:00