Wrap greenlet-spawning code inside a try/finally block

Summary:
Eben,

This is a patch extracted from the account deletion diff. It simply wraps the initial sync code inside a try/finally block so that the greenlets we spawn during the initial sync get killed when the main greenlet is killed.

Test Plan: Ran a sync.

Reviewers: emfree

Reviewed By: emfree

Maniphest Tasks: T330

Differential Revision: https://review.inboxapp.com/D380
Delete accounts

Summary:
Christine, Charles, Eben

I've implemented the minimum viable code for deleting accounts. There's not a lot of changes in this differential;  mostly I changed foreign keys definitions where needed. I also extended session_scope() to autocommit when needed.

One thing I'd like you to review in priority is the deletion logic. Right now it consists in stopping the account syncing, waiting 60 secs and and then marking the account as deleted.

This is needed because otherwise inbox-start may crash. I think it's okay to wait like this, though one minute is a little optimistic. What do you think about it?

Finally, I added a small script, `garbage-collect-db`, which removes accounts marked as deleted older than ten days.

Ps: migrations are coming in the next version of the review.

Test Plan: Ran a test which deleted accounts at teardown. Checked that the accounts were deleted.

Reviewers: spang, charles, emfree

Reviewed By: emfree

Differential Revision: https://review.inboxapp.com/D351
Eager-load account.namespace

We really never want the account but not the namespace.
Reduce IDLE timeout.

Summary:
This seems like the most expedient way to ensure that we detect flag changes
with at least reasonable latency.

Fixes T319.

Test Plan:
Mark a thread as read in the Gmail web UI; check that this gets
propagated to the API within a reasonable amount of time if (and only if) a
short idle timeout is set.

Reviewers: spang

Reviewed By: spang

Maniphest Tasks: T319

Differential Revision: https://review.inboxapp.com/D387
[events/when] Update the api to support the 'when' property for specifying times and dates to be more explicit.

Summary:
[events/when] More 'when' support as well as improved testing.
Note that the documentation needs to be overhauled for the new API and will be done in a separate commit.

Test Plan: run the new tests.

Reviewers: emfree

Reviewed By: emfree

Differential Revision: https://review.inboxapp.com/D382
Refactor IMAP sync.

Summary:
This commit restructures the IMAP sync engine logic to use a more
object-oriented design, favoring implementation inheritance over explicit
state-and-implementation passing.

The primary motivation for this is that I was finding it really challenging to
do surgery on the mailsync code, for two reasons. First, passing functions
around made it very difficult to see where any given function is being invoked,
because you have to know that create_gmail_message(...) may actually be called
as msg_create_fn(...), etc. Second, it's really hard to modify the state
that's being passed around, because you have to change like seven levels of
function parameters. This pattern was leading us to do weird stuff like reading the
account_id from the crispin_client, or repeatedly query for things we already in
principle know, like the active Namespace instance.
This carries a significant performance cost when aggregated over the lifetime
of a sync.

So this commit is essentially preparation for making targeted changes
to address both performance and correctness. Concretely, it does the following:
* Implement most logic in methods of the FolderSyncEngine class, which runs the
  sync state machine. Implement derived classes CondstoreFolderSyncEngine and
  GmailFolderSyncEngine, which override specific functionality for condstore
  sync and Gmail sync.

* Move the SyncMonitor logic (the thing that gets instantiated from the
  SyncService and starts the individual folder syncs) into its own module
  backends.imap.monitor. The SyncService actually instantiates lightweight
  derived classes GmailSyncMonitor, GenericSyncMonitor, etc. depending on
  provider, but the only difference among them is which type of
  FolderSyncEngine gets instantiated.

Smaller associated changes:
* Rename backends.imap.account to backends.imap.common, to prevent confusion
  over whether 'account' is an Account instance or a module.
* Use structlog's greenlet-local context facility to bind context to the logger
  on a per-greenlet basis. This means that we can just do log = get_logger() in
  in a greenlet and have it come with the right bound attributes, instead of
  needing to pass around a log object.
* Define 'mailsync_session_scope' as an alias for
  'session_scope(ignore_soft_deletes=False)'
* Remove some unused code.
* Clean up some parameter mismatches in condstore code.

This is obviously a pretty gnarly patch, but I think if we eat our wheaties now
it will pay off later.

Test Plan:
Working on it. Probably going to do a 'sync-diff' for various
providers, by running a sync with and without this change, and checking that
the results are the same.

Reviewers: khamidou, spang

Reviewed By: khamidou, spang

Subscribers: kav-ya, charles

Differential Revision: https://review.inboxapp.com/D378
[SCHEMA] Simplify transaction log construction.

Summary:
This commit implements a leaner, meaner transaction log. Instead of storing an
ORM-derived delta, only store a snapshot of the API representation of the
versioned object. This reduces the volume of data we store, makes constructing
the transaction faster, and removes some complexity left over from when we were
trying to infer syncback actions from the transaction log. It's way less
generic, but better suited to our actual application.

Includes some simplifications to the Lens model -- just removing parts that
would be broken by this change, and were part of webhooks but are unlikely to
be repurposed into ping.

Test Plan: Need to add some unit tests before landing.

Reviewers: spang

Differential Revision: https://review.inboxapp.com/D385
Use an S3 connection pool for blob saving.

It turns out that initializing a new S3 connection for every object you save to
S3 is really expensive. Instead, maintain a pool of worker greenlets, each of
which maintains a persistent S3 connection. (Note that an S3 connection cannot
be shared across greenlets.)