Commit graph

4244 commits

Author SHA1 Message Date
Juan Tejada aadb1182c0 [local-sync] Make the sync loop interruptible
Summary:
This commit introduces interruptible sync operations. Now, the `SyncWorker`, `FetchFolderList` operation and `FetchMessagesInFolder` operation can be interrupted at several p

To achieve this, this commit adds an Interruptible abstraction, which is an object that can run functions and interrupt them at points marked by the function. For more info o

This commit also splits up the SyncWorker a little bit to make it smaller, byadding a SyncbackTaskWorker.

Test Plan: manual

Reviewers: evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D3613
2017-01-09 14:42:57 -08:00
Evan Morikawa a722e48e0b fix(error): add comments and logging for RequestEnsureOnceError send error 2017-01-09 14:08:23 -08:00
Halla Moore f97d0204ae fix(showErrorDialog): Use a different modal when 'Show Details' is clicked
Summary:
When the error details are too long, the error dialog went off screen and
could not be closed. The native dialog doesn't have any scroll support and
you can only pass it plain text, so this diff moves the error details into
a non-native modal with a scrollable textarea.

Fixes T7388

Test Plan: tested locally

Reviewers: jackie, juan

Reviewed By: juan

Maniphest Tasks: T7388

Differential Revision: https://phab.nylas.com/D3601
2017-01-09 10:51:13 -08:00
Halla Moore 08a0883d21 fix(spinner): Use a constant spinner when loading inline images
Summary:
We used to use a progress-based spinner, but we never get any progress
updates while downloading files, so the spinner was always at 0 and
never visible.

The submodule-commit is D3609, which adds support for inline images

Test Plan: tested locally

Reviewers: evan, spang

Reviewed By: spang

Differential Revision: https://phab.nylas.com/D3610
2017-01-09 10:46:09 -08:00
Tomasz Finc 7484e6d4f8 Adding AppVeyor Slack notifications
Summary: So that we know the status of builds

Test Plan: Run the build. See it post to slack

Reviewers: juan, evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D3607
2017-01-09 10:28:14 -08:00
Evan Morikawa 183cbc4388 fix(lint) 2017-01-09 09:57:14 -08:00
Evan Morikawa c0e2943c26 bump(version): 0.5.4 2017-01-09 09:46:31 -08:00
Evan Morikawa 07a480853d bump(k2) 2017-01-09 09:45:53 -08:00
Jackie Luo 9267457d84 fix(archive): Designate role for archive folder 2017-01-06 16:54:09 -08:00
Evan Morikawa b8f126d45b bump(version): 0.5.3 2017-01-06 15:58:04 -08:00
Evan Morikawa 328c0c4633 fix(typo): don't list twice 2017-01-06 15:43:10 -08:00
Evan Morikawa df1343da37 feat(off): disable/hide snooze, mail rules, misc minor plugins 2017-01-06 15:39:09 -08:00
Tomasz Finc 2cf9e3a20a Removing node module cache for now to see if stops gyp rebuild from breaking
Summary: Trying to fix https://ci.appveyor.com/project/nylas/n1/build/2442

Test Plan: ... run the build

Reviewers: juan, evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D3603
2017-01-06 14:56:54 -08:00
Evan Morikawa 230127b57e bump(k2) 2017-01-06 14:33:45 -08:00
Jackie Luo c0596ef8e4 fix(category-picker): Hide starred label 2017-01-06 13:18:51 -08:00
Juan Tejada af677e3b43 fix(sync-status) When getting sync status, make sure account and progress data exists
Summary: See title

Test Plan: manual

Reviewers: evan, halla

Reviewed By: evan, halla

Differential Revision: https://phab.nylas.com/D3588
2017-01-06 11:33:06 -08:00
Juan Tejada f9d4974b51 fix(build) Temporarily remove tests 2017-01-06 09:58:55 -08:00
Tomasz Finc 32d2cbf309 Don't need to lint arclint
Summary: More files that don't need linting

Test Plan: ... run the build

Reviewers: evan

Reviewed By: evan

Subscribers: juan, evan

Differential Revision: https://phab.nylas.com/D3599
2017-01-05 16:56:15 -08:00
Halla Moore b455ae6023 fix(categories): Fix operations on categories
Summary:
- Make creating/renaming categories non-optimistic (this, along with the
    submodule commit D3593, prevents sub-categories with emtpy titles)
- Use SyncbackTaskAPIRequest in DestroyCategoryTask
- Don't get upset that renaming a category doesn't return a server id

Test Plan: local

Reviewers: juan, evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D3594
2017-01-05 16:47:07 -08:00
Evan Morikawa c873d8eb75 bump(k2) 2017-01-05 16:34:12 -08:00
Tomasz Finc beae37a26c Removing error-logger exclude as it didn't actually work. Removing linter for now
Summary: Almost there ...

Test Plan: ... run the build

Reviewers: evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D3597
2017-01-05 16:27:23 -08:00
Karim Hamidou dc25d1f180 [N1] Only show the "reauthenticate" dialog box when we're getting 401s
from the local sync engine.

Previously we'd show the dialog box when we'd get an error from
Clearbit.
2017-01-05 15:06:20 -08:00
Tomasz Finc 7cc1666279 fix(Linting errors)
Summary: Second attempt at not linting the error logger and tiny lint cleanup

Test Plan: run the build

Reviewers: evan, juan

Reviewed By: juan

Differential Revision: https://phab.nylas.com/D3591
2017-01-05 14:39:25 -08:00
Jackie Luo 9de1f756b4 fix(related-threads): Include from field in thread participants 2017-01-05 13:01:23 -08:00
Jackie Luo 360493567f fix(destroy-category): Process syncback request deltas correctly 2017-01-05 11:42:58 -08:00
Halla Moore 21db84f13f fix(Message): update fromJSON()
Summary:
- Handle `categories` if it exists, because clone() will call fromJSON()
    on the results of toJSON(), which populates `categories` instead of
    `folder` or `labels`
- Remove the else-if for `folder` and `labels`, because both can co-exist.
    Also concatenate the results from these two, rathering than overwriting.

Submodule commit is D3581, these two diffs together help make sure the
inflated messages in N1 have the right categories.

Test Plan: tested locally

Reviewers: juan, evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D3582
2017-01-04 17:50:29 -08:00
Tomasz Finc bf9dfa3727 Removing error logger from linting
Summary: Skipping linting for the error logger

Test Plan: Run the build

Reviewers: juan

Reviewed By: juan

Differential Revision: https://phab.nylas.com/D3583
2017-01-04 16:19:24 -08:00
Evan Morikawa 16cab4272b feat(send)
refactor(send): split delivery from sent folder stuffing

Summary:
See explanation in https://phab.nylas.com/D3577

Depends on D3577

Test Plan: manual

Reviewers: jackie, juan, halla

Reviewed By: juan, halla

Differential Revision: https://phab.nylas.com/D3578
2017-01-04 15:42:19 -08:00
Tomasz Finc 3d12b36294 Removing unit tests for now
Test Plan: Run the build

Reviewers: evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D3579
2017-01-04 11:33:42 -08:00
Mark Hahnenberg f3caf0b561 [thread-search] Fix archiving from search perspective
Summary:
We weren't removing the inbox category in the search perspective, so
things weren't actually being archived.

Test Plan: Run locally

Reviewers: juan, evan

Reviewed By: evan

Maniphest Tasks: T7389

Differential Revision: https://phab.nylas.com/D3575
2017-01-04 11:15:45 -08:00
Christine Spang 7541db7a65 bump(K2) 2017-01-04 11:09:10 -08:00
Juan Tejada 1ad337d345 fix(deps) Correctly fix debug version 2017-01-04 10:33:37 -08:00
Juan Tejada 22e4327cb0 fix(deps) Fix debug to v2.4.5. See #3139 2017-01-03 17:36:47 -08:00
Tomasz Finc e85954e1f6 Adding n1-next to AppVeyor builds
Test Plan: Run some builds

Reviewers: evan

Reviewed By: evan

Maniphest Tasks: T7377

Differential Revision: https://phab.nylas.com/D3574
2017-01-03 14:00:02 -08:00
Halla Moore 9e2f14513e feat(sync-status): Add messaging in other areas when syncing
Summary:
We want users to know that their account is still syncing if they're
looking for a message and end up at the bottom of a thread list.
This diff changes some of the wording around the messaging when
sync isn't complete and also adds a footer at the bottom of the
syncing thread lists. Additionally, we added a "Show Progress"
link that will expand the sync details in the lower left.

Addresses T7354

Test Plan: tested locally

Reviewers: juan, evan, jackie

Reviewed By: jackie

Differential Revision: https://phab.nylas.com/D3551
2017-01-03 13:27:15 -08:00
Evan Morikawa 0e36afa05e bump(version): 0.5.2 2017-01-03 09:32:59 -08:00
Evan Morikawa bec35ba82b bump(k2) 2017-01-03 09:32:39 -08:00
Jackie Luo e03d7b9df6 fix(multi-send): Check that other message exists 2016-12-29 16:00:30 -08:00
Mark Hahnenberg b99c5a671d fix(startLongConnection) Return the connection
Summary: We weren't doing this which was causing us to deref undefined later.

Test Plan: Run locally

Reviewers: juan, evan

Maniphest Tasks: T7355

Differential Revision: https://phab.nylas.com/D3561
2016-12-27 13:40:39 -08:00
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 baa9d7d363 bump(version): 0.5.1 2016-12-22 09:36:07 -08:00
Evan Morikawa 5bde45807a bump(k2) 2016-12-22 09:27:41 -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
Juan Tejada a0050a22d5 fix(sync-status):Use weighted percentage avg for sync status progress bar
Summary: Also move calculation to sync store, rename stuff a little bit

Test Plan: Manual :(

Reviewers: evan, jackie, halla

Reviewed By: jackie

Differential Revision: https://phab.nylas.com/D3547
2016-12-21 18:30:54 -05:00
Jackie Luo b5970e1e46 fix(initial-sync-activity): Update correct function name 2016-12-21 12:04:50 -08:00
Juan Tejada b29f46fdae fix(auth): Fix authentication notifications
Summary:
Depends on D3544 (K2 diff)

This commit ensures that auth notifications are showed when the
underlying sync worker fails and are cleared when an account is
successfully reconnected

To achieve this, we manually keep track and update syncStates where
appropriate via `Actions.updateAccount`, given that we have access to
N1's version of the account directly from local-sync.
Initially I was considering account delta stream to the cloud-api and the local-api, but that
just complicated things more than it helped.

This commit also fixes a bug with refreshing the gmail token in which we
we were only attempting a token refresh upon restarting the app

This addresses: T7346, T7305, T7335

Test Plan: Manual

Reviewers: halla, evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D3545
2016-12-21 07:23:09 -05:00
Evan Morikawa 1b75763d91 bump(k2) 2016-12-20 16:47:43 -08:00
Evan Morikawa 487dac31b3 fix(spec): fix asynchronous specs
Summary:
I believe I discovered why our tests intermittently fail, why those
failures cause a cascade of failures, and how to fix it.

The bug is subtle and it's helpful to get a quick refresher on how various
parts of our testing system work:

First a deeper dive into how Promises work:

1. Upon creating a new Promise, the "executor" block (the one that gets
   passed `resolve` and `reject`), gets synchronously run.
2. You eventually call `resolve()`.
3. The minute you call `resolve()`, Bluebird's `async.js` queues up
   whatever's downstream (the next `then` block)
4. The queue gets processed on every "tick".
5. Once the "tick" happens, our queue processes and downstream `then`
   blocks get run.
6. If any more Promises come in before the "tick", they get added to the
   queue. Nothing gets processed until the "tick" happens.

The important takeaway here is this "tick" in step 4. This "tick" is the
core of what makes Promises asynchronous. By default, Bluebird in our
Node-like environment uses `setImmediate` as the underlying
implementation.

Our test environment is different. We do NOT use `setImmediate` in our test
environment.

We use Bluebird's `Promise.setScheduler` API to implement our own "tick".  This
gives us much greater control over when Promises advance. Node's `setImmediate`
puts you at the whim of the underlying event loop.

Before today, our test "tick" implementation used `setTimeout` and
`advanceClock` triggered by `process.nextTick`.

Let me also quickly explain `setTimeout` in our test environment.

We globally override `setTimeout` in our test environment to not be based on
actual time at all. There are places in our code where we wait for several
hundred miliseconds, or have timeouts places. Instead of "sleeping" some amount
of time and hoping for the best, we gain absolute control over "time". "Time"
is just an integer value that only moves forward when you manually call
`advanceClock()` and pass it a certain number of "milliseconds".

At the beginning of each test, we reset time back to zero, we record
setTimeouts that come in, and as advanceClock gets called, we know if we need
to run any of the setTimeout callbacks.

Back to the Promise "tick" implementation. Before today, our testing "tick"
implementation relied our our stubbed `setTimeout` and our control of time.

This almost always works fine. Unfortunately tests would sometimes
intermittently fail, and furthermore cause a cascade of failures down the road.

We've been plauged with this for as long as I can remember. I think I finally
found how all of this comes together to cause these intermittent failures and
how to fix it.

The issue arises from a test like the one in query-subscription-pool-spec.  We
have tests here (and subtly in other yet unknown places) that go
something like this:

```
it("TEST A", () => {
  Foo.add(new Thing())
  expect(Foo._things.length).toBe(1)
})

it("TEST B", () => {
  expect(true).toBe(true)
})
```

At the surface this test looks straightforward. The problem is that
`Foo.add` may down the line call something like `trigger()`, which may
have listeners setup, which might try and asynchronously do all kinds of
things (like read the fs or read/write to the database).

The biggest issue with this is that the test 'finishes' immediately after
that `expect` block and immediately moves onto the next test. If `Foo.add`
is asynchronous, by the time whatever downstream effects of `Foo.add` take
place we may be in a completely different test. Furthremore if those
downstream function errors, those errors will be raised, but Jasmine will
catch them in the wrong test sending you down a rabbit hole of dispair.

It gets worse.

At the start of each test, we reset our `setTimeout` stub time back to
zero. This is problematic when combined with the last issue.

Suppose `Foo.add` ends up queuing a downstream Promsie. Before today, that
downstream Promise used `setTimeout(0)` to trigger the `then` block.

Suppose TEST A finishes before `process.nextTick` in our custom scheduler
can call `advanceClock` and run the downstream Promise.

Once Test B starts, it will reset our `setTimeout` stub time back to zero.

`process.nextTick` comes back after Test B has started and calls
`advanceClock` like it's supposed to.

Unfortunately, because our stub time has been reset, advanceClock will NOT
find the original callback function that would have resolved `Foo.add`'s
downstream Promise!!!

This means that Bluebird is now stuck waiting for a "tick" that will never
come anymore.

Since Bluebird thinks it's waiting for a "tick", all future Promises will
get queued, but never called (see Step 6 of the Promise description
above).

This is why once one test fails, downstream ones never complete and
Jasmine times out.

The failure is intermittent because `process.nextTick` is racing agianst a
test finishing, the next one starting, and how many and how far downstream
promises are setup.

Okay. So how do we fix this? First I tried to simply not reset the time back to
zero again in our stubbed time-override. This doesn't work because it simply
exposes the diasterous consequences of downstream Promises resolving after a
test has completed. When a test completes we cleanup objects, unmount React
components. Those downstream promises and timeouts come back and throw all
kinds of errors like: "can't read property x of undefined" and "can't find a
match for component X".

The fix that works the best is to simply MAKE PROMISES FULLY SYCNRHONOUS.
Now if you look at our custom Promise Test Scheduler in time-override,
you'll see that it immediately and sychronously calls the function. This
means that all downstream promises will run BEFORE the test ends.

Note that this is designed as a safeguard. The best way to make a more
robust test is to declare that your funtion body is asynchronous. If you
call a method that has downstream effects, it's your responsibility to
wait for them to finish. I would consider the test example above a very,
very subtle bug. Unfortunately it's so subtle that it's unreasonable to
expect that we'll always catch them. Making everything in our testing
environment synchronous ensures that test setup and cleanup happen when we
intuitively expect them to.

Addendum:

The full Promise call chain looks something like this:

-> `Promise::_resolveCallback`
-> `Promise::_fulfill`
-> `Promise::_async.settlePromises`
-> `AsyncSettlePromises`
-> `Async::_queueTick`
-> CHECK `Async::_isTickUsed`
-> `Async::_schedule`
-> `TimeOverride.scheduler`
-> `setTimeout`
-> `process.nextTick`
-> `advanceClock`
-> `Async::_drainQueues`
-> `Async::_drainQueue`
-> `THEN BLOCK RUNS`
-> `Maybe more things get added to queue`
-> `Async::_reset`
-> `Async::_queueTick` works again.

Test Plan: They now work

Reviewers: halla, mark, spang, juan, jackie

Reviewed By: juan, jackie

Differential Revision: https://phab.nylas.com/D3538
2016-12-20 16:47:26 -08:00
Evan Morikawa 7f36d2b4b2 bump(k2) 2016-12-20 13:08:50 -08:00
Juan Tejada 454676581a fix(sync-status) Fix off by one error in store 2016-12-20 08:25:20 -08:00